Building a Windows Service application using Topshelf — Part 2 of 2: Customizing
Source code from this blog can be found on GitHub.
Topshelf provides several customization features. One of them is customizing the Windows Service information that is shown in Services.
The Windows Service information can be set from the command line when installing, through host level configuration and using the project properties. I prefer using the project properties because then there is a single point of entry for the Windows Service information and the executable information.

The method UseAssemblyInfoForServiceInfo is called to force Topshelf to use the project properties for retrieving the Windows Service information.
The startup type can be set from the command line when installing but this can also be done using the hostConfig. The self-explanatory options StartAutomatically, StartAutomaticallyDelayed, StartManually and Disabled are available for this.
For security reasons it sometimes is required to run the Windows Service with specific credentials. Topshelf provides functionality on host level configuration to use the Network Service ( RunAsNetworkService), Local System ( RunAsLocalSystem), Local Service ( RunAsLocalService) or a specified username and password ( RunAs). There is also an option available to prompt the user for an username and password during installation ( RunAsPrompt). Just like previous customizations, the credentials can also be set from the command line when installing. Please note that the credentials are not used when running the Console Application from Visual Studio.

After rebuilding and executing the Console Application with uninstall, install and start from the command line, the Windows Service has been customized as shown in Services.

Dependencies
A Windows Service can require other Windows Services to be running in order to function properly. In that case, the Windows Service is dependent on other Windows Services and therefore it should not start before the other Windows Services are up-and running.
The host level configuration method DependsOn can be called with a given service name to add a dependency. Topshelf also has pre-defined dependencies for the commonly used Windows Event Log ( DependsOnEventLog), Microsoft SQL Server ( DependsOnMsSql), Microsoft Message Queueing ( DependsOnMsmq) and Internet Information Server ( DependsOnIis). The dependencies are not applied when running the Console Application from Visual Studio.
In the demo dependencies on Windows Event Log and Print Spooler (service name: “Spooler”) have been added.

When the Windows Service is rebuild and reinstalled, the dependencies can be seen on the Dependencies tab in Services.

Recovery
Recovery actions can be configured to automatically respond to failures. Recovery actions can be defined for first, second and subsequent failures.

The order in which the recovery actions are defined in the Console Application determines the configuration of the failures. Therefore, in order to configure the Windows Service as shown above, the code below is added.

Logging
Windows Services run unattended and there is no user interface so therefore logging is essential for maintenance. Topshelf supports the logging libraries Nlog and Serilog but I prefer to use Log4Net because I have used it before and it has some great features. To use the Log4Net implementation, it must be added as separate NuGet package to the Console Application (same for the other libraries).

After adding the NuGet package Log4Net must be configured. I defined a ConsoleAppender for output to the console and a RollingFileAppender for output to the logfile in the log4net.config. This configuration must be initialized by executing XmlConfigurator.Configure() in the Main method before the HostFactory is initialized to overrule TraceSource which is used by the default. In the MyWindowsService a log object can now be implemented for writing custom logging.

When running the Console Application from Visual Studio the output (generated by Topshelf and the custom logging) is written to the console and logging file. The Windows Service writes this output only to the logging file.

More events
So far only the Start and Stop events have been implemented for the Windows Service, but a Windows Service can also be paused and resumed. These events can be enabled by EnablePauseAndContinue. With EnableShutdown the Shutdown event will be raised when the host computer is turned off. The methods WhenPaused, WhenContinued and WhenShutdown must be used for defining the event callbacks. Additional events are WhenSessionChanged (for change events received from a Terminal Server session) and WhenPowerEvent (for events related to power changes, for example when the host computer goes into suspended mode). Unfortunately, none of these events cannot be invoked from the console using shortcut keys (like Control+C for stopping the Windows Service) so for debugging the event callbacks must be invoked from source code.

Until now all events described are related to the state of the Windows Service itself, but Topshelf also provides events that are related to installing ( BeforeInstall and AfterInstall) and uninstalling ( BeforeUninstall and AfterUninstall) the Windows Service. In case the installation fails, the events BeforeRollback and AfterRollback can be used.
Summary
Topshelf is an easy to use and understand framework for developing, debugging, configuring and installing a Windows Service application. Although not all Windows Service events can be emulated (for example: Pause and Resume), it will save you lots of time because it can be debugged in the Console Application project template!
Click here to read part 1 of 2: getting started.
Thank you for reading my story. You can read about Twyzer on https://twyzer.nl (in Dutch) or click here for the English translation.