Simple Windows service with Topshelf

What is Topshelf? The authors describe it as

… a framework for hosting services …

Topshelf makes developing and installing Windows services super easy.

In short, you develop and debug classic console app and when it is ready to be deployed, you can then install it with just one simple command:

MySimpleService.exe install

Sounds good? If so, below is a simple step by step guide of how you can achieve it:

1. Create application

Create a new Console application and grab the Topshelf package from nuget

Install-Package Topshelf

While you are at it, I would also recommend to install some logging library. Since this is going to be something running in the background, logs become the only place to look for info when diagnosing problems. My logging library of choice is Serilog and Topshelf provides a nice integration package, so I’ll install it as well.

Install-Package Topshelf.Serilog

2. Create service class

Next create the service class. I named mine MySimpleService. In here place methods, which will be called at specific lifetime events of the Windows service. At minimum, add some methods for starting and stopping the service.

public class MySimpleService
{
    readonly LogWriter _log = HostLogger.Get<MySimpleService>();
    public void Start()
    {
        _log.Info("Starting MySimpleService ...");
        // do some work here
        Console.WriteLine("Hello from MySimpleService");
    }
    
    public void Stop()
    {
        _log.Info("Stopping MySimpleService ...");
        // clean up
    }
}

3. Register service in Topshelf

The last step is to register our service class in Topshelf. Jump to Program.cs and add:

private static void Main(string[] args)
{
    HostFactory.Run(configure =>
    {
        configure.Service<MySimpleService>(service =>
        {
            // here you can pass dependencies and configuration to the service
            service.ConstructUsing(s => new MySimpleService());

            service.WhenStarted(s => s.Start());
            service.WhenStopped(s => s.Stop());
        });
 
        configure.StartAutomatically();
        configure.EnableServiceRecovery(r => r.RestartService(0));
        configure.RunAsLocalSystem();
 
        configure.SetServiceName("MySimpleService");
        configure.SetDisplayName("My Simple Service");
        configure.SetDescription("This is my simple service");
 
        configure.UseSerilog(CreateLogger());
    });
}
 
private static ILogger CreateLogger()
{
    var logger = new LoggerConfiguration()
        .WriteTo.File("log.txt", Serilog.Events.LogEventLevel.Debug)
        .CreateLogger();
    return logger;
}

The great thing about Topshelf is the intuitive API and the whole configuration is pretty self explanatory.

Now you are ready to hit F5. If everything went well, you should see something like this: running in debug

In the example above I configured only the basic functionality. There is a lot more options, so I recommend checking out the official docs and also the samples available on github.

Once you are ready to install the service, open the command line as Administrator (otherwise the installation will fail), browse to the directory of the exe and call it with install argument. For me it is:

MySimpleService.exe install

It should give you a message about installation being successful. You can now check out in the Services window your newly registered Windows service. registered services

Comments

comments powered by Disqus