C# Basics: Creating a Windows Service

February 28, 2010 by C#  

Windows services are basically "long-running" executables that performs certain functions (services) that doesn't require user intervention (runs in the background e.g. like the ASP.net State Service, indexing service).

You can manage these services within your services management console, we can start/stop/pause etc these services.

The basic structure of a service within the .net realm using C#, looks something like this:

using System.ServiceProcess;
using System.Threading;

namespace myService
    class Service : ServiceBase
        static void Main()
            ServiceBase.Run(new Service());

        public Service()
            Thread thread = new Thread(Actions);

        public void Actions()

Notice that we inherited from ServiceBase, you can find this class within the System.ServiceProcess assembly & namespace.

Within our entry point (void Main), we call a static method named Run from our ServiceBase class and pass an instance of our service to the method, you may also pass multiple(Array) instances of classes derived from ServiceBase to this method e.g. have multiple & different services run within one process.

You will also notice that I've created a thread within the constructor, this becomes necessary since our service needs to start up within a certain time frame, else it will time out - aborting our service - moving logic to a thread will insure that the service starts in a timely manner.

Notice what happens when you call the actions method directly from within the constructor without using a thread

There is also a number of methods one can override within the derived class, onstop/onshutdown/onpause/oncontinue etc - relating to actions we can control using the services management console - some relating to system wide events - like shutting down the server/pc, or putting your laptop into sleep mode e.g. onpowerevent.

These events won't be raised automatically though, we need to enable them, like seen in the following snippet:

this.CanShutdown = true;
this.CanStop = true;
this.CanHandlePowerEvent = true;

To deploy/install this service to a server/pc, create a class inheriting from the installer class (available within the System.Configuration.Install assembly) like this:

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

public class myServiceInstaller : Installer
    public myServiceInstaller()
        ServiceProcessInstaller serviceProcessInstaller = new ServiceProcessInstaller();
        ServiceInstaller serviceInstaller = new ServiceInstaller();
        serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
        serviceInstaller.DisplayName = "myService";
        serviceInstaller.StartType = ServiceStartMode.Automatic;
        serviceInstaller.ServiceName = "myService";

You can install the service via a batch file using the following commands:

SET PATH=%path%;%windir%\Microsoft.NET\Framework\v2.0.50727

REM Uninstall the Service if it exists already

InstallUtil /u myService.exe

REM Install the Service

InstallUtil /i myService.exe

REM Start the Service once we're done
net start myService

Alternatively one can create a .NET installer via Visual Studio e.g.
  • Add New Project
  • Setup and Deployment
  • Setup Project
  • Add service primary output

Add the primary output of the solution containing the installer class to the install & uninstall custom actions within the setup like seen in the following image.

Some tips:


I heard a lot of people complaining about how difficult it is to debug a service, since we can't just simply run it from visual studio - it does however become rather simple if we add Debugger.Break() (one of the lovely System.Diagnostics methods) to our code, this will open up a window asking us which application we wish to use in debugging our code (Visual Studio for example). (Remember to set interact with desktop within the properties of your service from the services management console)


Something else to consider, when using the registry within services, is that generally we use a local system account (the logon for the service), which accesses different keys within the registy, than our current user (Generally you can access keys from the "HKEY_USERS\.DEFAULT" key).

Remote Desktop:

When the "Allow Service to interact with desktop" checkbox is ticked and you're attempting to interact with the desktop via remote desktop the interaction UI will only appear in the console/admin session.
mstsc /console (XP/2003)
mstsc -admin (Vista/7/2008)

Manually remove service

SC delete "myService"

Leave a Comment