Writing a Windows Service

Creating

The steps for creating a Windows Services are pretty simple.

Open Visual Studio and create a new Windows Service Project. This will create a Program.cs with the relevant code to instantiate the service and then run it. The defaults service files (Service1.cs) contains an object derived from the ServiceBase. Here we implement our code. So when the Service starts the Onstart method is called, here we run whatever code we require to run the service and the OnStop (as the name suggests) we stop the code. There’s also OnPause and OnContinue overrides if needed.

Next we need to create an installer to allow the service to be installed in the Services control app.

Open the Service1.cs (or whatever the service is now called) designer and right mouse click on the background. Select Add Installer. An installer has been added which has the service name of your service and is set-up by default to install on the user’s account and in Manual startup mode. Obviously changes these to suit, plus add a description of the service which will be displayed in the Service control app.

If, on the other hand, you don’t have a Service1 designer or you wish to add an installer by hand, simple create a new C# class and add the following (bare minimum) code

[RunInstaller(true)]
public partial class MyInstaller : Installer
{
   private ServiceProcessInstaller serviceProcessInstaller;
   private ServiceInstaller serviceInstaller;

   public MyInstaller()
   {
      serviceProcessInstaller = new ServiceProcessInstaller();
      serviceInstaller = new ServiceInstaller();

      serviceProcessInstaller.Password = null;
      serviceProcessInstaller.Username = null;
			
      serviceInstaller.ServiceName = "Orchestator.Service";

      Installers.AddRange(new Installer[] { serviceProcessInstaller, serviceInstaller });
   }
}

Note: The username and password are set to null, hence when you try to install this service it will ask you for the username and password to login with. Alternatively you can set the Account on the serviceInstaller to ServiceAccount.LocalService which will not require the username/password dialog to be displayed as per the following code

serviceProcessInstaller.Account = ServiceAccount.LocalService;

Installing

To install the service without creating a fully fledged setup application simply run

installutil.exe

and to uninstall

installutil.exe /u

If you have no supplied the username and password you’ll be prompted to supply it, you will need to supply the fully qualified username, including domain or for a local user account use .\username (where .\ indicates the local machine). .\ on it’s own can be used to indicate the local machine but in the Services applet it will display .\ as Log On As, whereas you might notice other local service logins show Local Service. We can easily alter out Installer class to allow for this as outlined previously.

Debugging

Due to the time limit for startup (30 seconds) it can be difficult to debug a service as it starts. The best solution to this is to create a console app which mimics the startup process. Once the service is running we can attach to it’s instance like any other app.