C# Basics: Creating a Windows Service
February 28, 2010 by
Christoff Truter
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);
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 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;
[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 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
PAUSE
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:
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 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)
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)
Manually remove service
SC delete "myService"
thank you July 6, 2021 by r s
thank you for providing this information , currently trying to do this very thing .