Simple Windows service with Topshelf
Mon, Jan 9, 2017What 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:
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.