NetCore Tutorials - NetCore 2.2 Console Hosted As A Windows Service


The purpose of this handy guide is to get NetCore on premise as a service hosted like a WindowsService.

  1. Create a Program.cs that starts the service similar to a ServiceBase inherited service.
  2. Demonstrate the template for running services.

Getting Started


NuGets

We only really need one main NuGet package and thats DasMulli.Win32.ServiceUtils. Its source can be found here with some basic documentation to get started.


Program.cs

using DasMulli.Win32.ServiceUtils;
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace NetCore.HostedAsService
{
    public class Program
    {
        public static LongRunningService _longRunningService { get; set; } = null;

        public static async Task Main(string[] args)
        {
            _longRunningService = new LongRunningService();
            var serviceHost = new Win32ServiceHost(_longRunningService);

            if (!Debugger.IsAttached) { serviceHost.Run(); }
            else
            {
                AppDomain.CurrentDomain.ProcessExit += new EventHandler(GracefulServerShutdown);

                await Console.Out.WriteLineAsync("LongRunningService running as a console...");

                _longRunningService.Start(null, null);

                Thread.Sleep(Timeout.Infinite);
            }
        }

        private static void GracefulServerShutdown(object sender, EventArgs e)
        {
            _longRunningService.Stop();
        }
    }

    public class LongRunningService : IWin32Service
    {
        public string ServiceName => "LongRunningService";

        public void Start(string[] startupArguments, ServiceStoppedCallback serviceStoppedCallback)
        {
            // Do Stuff To Setup Work
        }

        public void Stop()
        {
            // Do Stuff To Stop Work (Graceful Shutdown)
        }
    }
}

Summary

What you see here is almost like a ServiceBase host service setup. LongRunningService has Start / Stop. Main only does one thing really and that is start/stop the service as a serviceHost or as a console application (if Debugger is Attached). That's optional too, just to aid local development.


Installing in Windows

There are two options, one via dotnet console and the other using powershell and SC.exe. More details are found at dasMulli's Github.

// dotnet install example
dotnet restore
dotnet run --register-service

// dotnet uninstall example
dotnet run --unregister-service

//You can then register your service via sc.exe (run cmd / powershell as administrator!):
// powershell install example
sc.exe create LongRunningService DisplayName="LongRunningService" binpath="C:\Program Files\dotnet\dotnet.exe C:\path\to\LongRunningService.dll --run-as-service"

// powershell uninstall example
sc.exe delete LongRunningService

Summary

That's pretty much all there is to get it working. The library is not without issues but for quick and easy setups it should do the job for hosted systems of NetCore based applications. This goes well with the distributed hangfire processing. You can host your HangFire process in a Windows Service even though it is a NetCore application.