Writing a Windows service is usually a tedious task, and Topshelf offers a pretty interesting alternative that’s far less tedious than the default template that comes with Visual Studio.
Although I could list quite a few interesting things about Topshelf, I’ll stick with one that’s essential for me: it lets a console application be a Windows service. This means you can use the console application during development or run it on its own, but you can also install that console application as a Windows service just by passing a parameter when running it.
Using Topshelf to create a Windows service is very simple. I’m going to describe the basic steps needed to get a service going, although we can make it quite a bit more complex later:
- We create a console application and install the Topshelf package
- We add a class containing the logic of the service we want to create. The skeleton could look like this:
public class ServiceRunner {
public void Start() {
// Code to run when the service starts
}
public void Stop() {
// Code to run when the service stops
}
}
- We modify the Main class to configure the service:
static void Main(string[] args) {
HostFactory.Run(x =>
{
x.Service<ServiceRunner>(sc =>
{
sc.ConstructUsing(name => new ServiceRunner());
sc.WhenStarted(rn => rn.Start());
sc.WhenStopped(rn => rn.Stop());
});
x.RunAsLocalSystem();
x.SetDescription("Service description");
x.SetDisplayName("DisplayName");
x.SetServiceName("Service name");
});
}
You can find many more details in the documentation. For example, besides configuring the code to run on start (WhenStarted) or on stop (WhenStopped), we can configure the behavior for pause (WhenPaused), continue (WhenContinued), and shutdown (WhenShutdown).
Once this is done, we have a console application that we can run on its own, debug from Visual Studio, or install as a service, and Topshelf will take care of running the right code when the service starts. To install the service you just need to run the console application with the “install” parameter, and to uninstall it, with the “uninstall” parameter.
Something very important to keep in mind is the user the service will run as. For example, if the service is going to use Owin to host a website or an API, this sample code won’t work, because if the service starts as LocalSystem it won’t have the right permissions.
You can pass other parameters to configure the behavior you want for the service in terms of startup mode, the user it runs as, running commands after installation, etc. The best thing is to check the documentation to keep up with all the options.