Writing your first Windows Service

What is Windows Service and what is it for?

It is a computer program that operates in the background without any user interaction and user interface.

After Windows XP there are several methods in Windows that protects itself from unwanted services. So it’s a bit tricky to create one in Visual Studio. The first and simpliest thing is to create a new Class Library project: WindowsService. After creating it, modify the project properties Output Type from Class Library to Windows Application. Otherwise you’ll get Windows Service Error 193 0xc1 when trying to start your new service. After this project modification your built result will be an EXE file, not DLL.

First of all you have to add some references to your project:

  • System.Configuration.Install
  • System.ServiceProcess

Now you can add Windows Service as a new item, but this time I suggest you to add only a new Class, so every properties and methods will be visible and should be created by yourself. So let’s add 2 new classes to our project: MyWindowsService.cs and MyWindowsServiceInstaller.cs

The first one will contain our methods of the service, the second one will be responsible for the service installation. Of course this installation class can be replaced by automatic code generation of the Design View of the service class.

In our MyWindowsService.cs file set inheritance of the class from ServiceBase (using of System.ServiceProcess is needed!)

using System.ServiceProcess;

namespace WindowsService
{
    class MyWindowsService : ServiceBase
    {
    }
}

To be able to view every initialized property in design mode, add a new private method named InitializeComponent().

private void InitializeComponent()
{
    this.ServiceName = "MyWindowsService";
    this.AutoLog = false;
    this.CanHandlePowerEvent = true;
    this.CanHandleSessionChangeEvent = true;
    this.CanPauseAndContinue = true;
    this.CanShutdown = true;
    this.CanStop = true;            
}

If you set these properties in your constructor, then you won’t see them in design mode:

Now create the constructor and call this InitializeComponent method:

public MyWindowsService()
{
    InitializeComponent();
}

Now override all those methods that usually used when creating Windows Service:

  • Dispose
  • OnStart
  • OnStop
  • OnPause
  • OnContinue
  • OnShutdown
  • OnCustomCommand
  • OnPowerEvent
  • OnSessionChange

I won’t describe these methods, because every time you type override in Visual Studio and press TAB, you’ll have a list of all overridable methods with their descriptions. Selecting the mentioned method after pressing TAB, you’ll have the base code inserted. Now leave them as they are (they all call their parent method with that base. command).

Finally create an entry point by creating the Main() static method:

static void Main()
{
    ServiceBase.Run(new MyWindowsService());
}

That’s all. You’re first Windows Service is ready to be installed. As you can see it won’t do anything after successfully installation. The above code only demonstrates the procedure of creating it. You can add for example any BackgroundWorker and call them in your OnStart() method after the base calling.

Now open the MyWindowsServiceInstaller.cs file, add 3 using:

  • System.ComponentModel
  • System.Configuration.Install
  • System.ServiceProcess

The ComponentModel is responsible for attributes given right before the class name. In this case, this is the RunInstaller attribute that tells InstallUtil.exe (the program that you will use when you want to install the service) which class constructor should be called.

The Configuration.Install is responsible for the collection of installers that should be executed when service is being installed.

The ServiceProcess is responsible for building the installer and the service itself.

This class should be inherited from Installer class and will have only one method: its constructor:

using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;

namespace WindowsService
{
    [RunInstaller(true)]
    public class MyWindowsServiceInstaller : Installer
    {
        public MyWindowsServiceInstaller()
        {
            ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
            ServiceInstaller serviceInstaller = new ServiceInstaller();

            serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
            serviceProcessInstaller.Username = null;
            serviceProcessInstaller.Password = null;

            serviceInstaller.DisplayName = "My new Windows Service written in C#";
            serviceInstaller.Description = "Here's the description of my Windows Service";
            serviceInstaller.StartType = ServiceStartMode.Automatic;

            serviceInstaller.ServiceName = "MyWindowsService";//The same as in the MyWindowsService constructor

            this.Installers.Add(serviceProcessInstaller);
            this.Installers.Add(serviceInstaller);
        }
    }
}

Now build your solution and you’ll get 2 files. In my case WindowsService.exe and WindowsService.pdb

Copy these 2 files into a new folder. Your service will run from here, so create a folder that won’t be deleted later!

Start a new command line by typing cmd. In the upcoming windows navigate to c:\Windows\Microsoft.NET\Framework\v4.0.30319 (or any version that is at least 4) and type:

InstallUtil.exe /i c:\myfolder\WindowsService.exe

After successful installation and typing services.msc in your command line, you’ll see your service in the service list. Right click on it and press Start. It should be started now.

If you want to uninstall this Windows Service, just type the following in command line:

InstallUtil.exe /u c:\myfolder\WindowsService.exe

You can add to your %PATH% the directory of Microsoft.NET\Framework… so you don’t have to start InstallUtil.exe from that directory, but this is another lesson, called Managing Windows Desktops. 🙂

One more important thing: most of the Windows Service must be run under elevated privileges! So everytime you try to install your service from command line, do not forget to start cmd.exe with elevated privileges (right click -> run as administrator)! In this case everything you start from command line will be started with admin rights! It’s important when you create a Windows Service for a company where all the users have no admin rights.