In this weeks post id like to give a mention to a very fine nuget package called TopShelf, TopShelf is essentially a container (or bootstrapper) for running Windows Services, it shields the developer from having to worry about the low level window service plumbing code & lets them run a windows service with minimal effort in debug mode within VS & also provides much neater cmd line syntax for installing/un-installing.
Any developer who has built or maintained windows services knows the pain of debugging these applications or installing them. A typical windows service looks like following
When this is run directly in VS it will give you this error
This can typically be fixed by applying following technique..
- Change the Windows Service project type from ‘Windows Application’ to a ‘Console Application’.
- Replace above static Main method code with following:
When you run this in VS now under either debug or release the service will run as expected & can allow you to debug (the above just prints hello world with the current time each second).
All of this is a valid work around BUT can be a little time consuming, cumbersome & also not ideal to having to write boiler plate code specifically for debugging purposes, installing the service also involves a bit of heavy command line syntax too.
Step forward TopShelf..
Setting up a windows service from scratch using this library involves 4 steps:
- Create a console application
- Install the Topshelf NUGET package,
- Configure a startup class
- Run the service from within VS
TopShelf has a fluent API that is easy to use, some very simple examples are show cased here, # 3 above is the HelloWorldServiceManager class which contains two methods Start() & Stop() that are wired up in the below code under WhenStarted & WhenStopped() calls.
Also notice the nice API methods SetDescription, & SetDisplayName which should be self explanatory, pretty cool right?
The HelloWorldServiceManager class Start & Stop methods just contain a thread which fires off every second printing to console screen
The other nice thing as i mentioned earlier about using TopShelf if you haven’t noticed already on above screenshots is that nowhere are the low level windows service framework code referenced i.e.: ServiceBase, this is all abstracted away under the hood by TopShelf so you the developer just worry about wiring the package up & then writing your own custom code that gets on with solving business requirements.
Installing/Un-installing the service on the Service Control Manger (SCM) is simplified through TopShelf cmd line syntax. Navigate to the bin folder of the service via cmd line, & run either:
- NameOfWindowsService.exe -install
- NameOfWindowsService.exe -uninstall
There is a host of other features it offers as well like exception handling, logging & dependancy injection, it also supports parameters being supplied @ startup of the service. Note: Some of these features will require additional TopShelf nuget package to be installed.
The one small thing id like to see improved upon with TopShelf is the documentation, while i have found it great when learning the tool initially, it is a bit outdated (written in 2011) so it could do with a refresh/update of content, some of this could be about the additional nuget packages that need to be installed for supporting additional requirements like using parameters @ startup which i had to do a bit of digging on.
Saying all that, its a terrific package to work with & has made my life much easier in dealing with Windows Services, something i approached with a little trepidation in days gone by just because of the drawbacks i covered above.
A side note – i have only used TopShelf with the .NET 4.6.1 framework, at time of writing no support exists yet for .NET Core 2 but am sure this will change soon enough.
So if you build windows services & have struggled with the points i raised above, fear not, reach for the top shelf @ the nuget store and enjoy frictionless windows service development for ever more!