C# Basics: Creating a Windows Service

Windows services are basically executables that performs certain functions that doesn't require user intervention (runs in the background e.g. the ASP.net State Service) - for example, recently I created an indexing service, that extracts text from files (using Ifilters) and stores the text within some database.

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 myWebservice
{
    class Service : ServiceBase
    {
        static void Main()
        {
            ServiceBase.Run(new Service());
        }
 
        public Service()
        {
            Thread thread = new Thread(Actions);
            thread.Start();
        }
 
        public void Actions()
        {
            Thread.Sleep(500000);
        }
    }
}
 

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 a 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.

To deploy/install this service to a server/pc, create a class inherting from the installer class (available within the System.Configuration.Install assembly) like this:
 
using System.ComponentModel;
using System.Configuration.Install;
using System.ServiceProcess;
 
[RunInstaller(true)]
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";
        this.Installers.Add(serviceProcessInstaller);
        this.Installers.Add(serviceInstaller);
    }
}
 

You can create a .net installer app to deploy the service or simply install it via a batch file running the following commands: SET PATH=%path%;%windir%\Microsoft.NET\Framework\v2.0.50727 REM Uninstall the Service if it exists already InstallUtil /u myWebservice.exe REM Install the Service InstallUtil /i myWebservice.exe REM Start the Service once we're done net start myService PAUSE
Some tips:

Debugging:

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 becomes 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)

Registry:

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.
e.g.
mstsc /console (XP/2003)
mstsc -admin (Vista/7/2008)






Post comment

Name *
Email
Title
Body *
Security Code
*
* Required fields

Latest Posts

Top 5 posts

Simple WYSIWYG Editor


Creating a WYSIWYG textbox for your website is actually quite simple.
2007-02-01 12:00:00

Moving items between listboxes in ASP.net/PHP example


Move items between two listboxes in ASP.net(C#, VB.NET) and PHP
2008-06-12 17:07:43

Cross Browser Issues: Firefox Word Wrapping


Firefox word wrapping issues
2008-06-09 09:51:21

Populate a TreeView Control C#


Populate a TreeView control in a windows application.
2009-08-27 16:01:03

What time will bring



2007-02-22 12:00:00