How to create a Simple Windows Service in C#

Your Ad Here

We all know what a Windows Service is - a long running executable that's designed to work without user interaction. They can be configured to start when the system boots and they can be run without any users logged into the system. This tutorial is going to provide step-by-step instructions on how to build a Windows Service using C# and .NET.

The first thing you're going to want to do is create a new Console Application in Visual Studio. I like to start building services as console applications so they can easily be tested and debugged before converting them to services.

New Console Application Dialog

In order to build services, we depend on some .NET objects location in the System.ServiceProcess and System.Configuration.Install assemblies. Go ahead and add those references to your project.

Visual Studio Project References

When you created the project, Visual Studio should have created a file called Program.cs, which looks something like this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyWindowsService
{
class Program
{
static void Main(string[] args)
{
}
}
}

The only thing we need to do in order to make this class into a service is make Program extend System.ServiceProcess.ServiceBase.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
namespace MyWindowsService
{
class Program : ServiceBase
{
static void Main(string[] args)
{
}
}
}

By extending ServiceBase, we're given a bunch of service related functions we can override. At a minimum, every service should override OnStart and OnStop. These are where, as the names imply, your custom logic should go when the service is started and stopped.

class Program : ServiceBase
{
static void Main(string[] args)
{
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
//TODO: place your start code here
}
protected override void OnStop()
{
base.OnStop();
//TODO: clean up any variables and stop any threads
}
}

There are several other functions beyond start and stop like pause, continue, and shutdown, but they're not needed for a basic service. For all available functions, check out the ServiceBase member list on MSDN.

Now we need to add some information about our service - like a name. Let's add a constructor to Program and put it there.

class Program : ServiceBase
{
static void Main(string[] args)
{
}
public Program()
{
this.ServiceName = "My Service";
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
//TODO: place your start code here
}
protected override void OnStop()
{
base.OnStop();
//TODO: clean up any variables and stop any threads
}
}

The constructor is where you'd also set lots of other information about your service (if the default settings wouldn't work). These can include things like which events it can handle, what operation it can do (pause, stop, etc.), and what event log it should log information to (application, system, etc.). For us, however, the default settings will work just fine.

We're very close to having a finished service. All that left is to tell Windows what service to run when your application it executed. Just like normal applications, execution begins in the Main function. This is where we'll create an instance of our service and tell it to run.

class Program : ServiceBase
{
static void Main(string[] args)
{
    ServiceBase.Run(new Program());
}
public Program()
{
this.ServiceName = "My Service";
}
protected override void OnStart(string[] args)
{
base.OnStart(args);
//TODO: place your start code here
}
protected override void OnStop()
{
base.OnStop();
//TODO: clean up any variables and stop any threads
}
}

That's it! The service implementation is complete. We can't install it yet though, because we haven't implemented an installer. To do that we need to add another class to our project called MyWindowsServiceInstaller.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyWindowsService
{
class MyWindowsServiceInstaller
{
}
}

When Visual Studio creates a class for you, it doesn't automatically make it public. It's very important that this class be made public. When you install a service, the installer will look through your assembly for public classes with a specific attribute. If it's not public, it won't find it.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MyWindowsService
{
public class MyWindowsServiceInstaller
{
}
}

This class needs to extend System.Configuration.Install.Installer and be given a RunInstaller attribute. This is the attribute that the service installer looks for when installing your service.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration.Install;
using System.ComponentModel;
namespace MyWindowsService
{
[RunInstaller(true)]
public class MyWindowsServiceInstaller : Installer
{
}
}

Now we need to configure how we want our service installed. We'll do this in the constructor for the class we just created.

[RunInstaller(true)]
public class MyWindowsServiceInstaller : Installer
{
public MyWindowsServiceInstaller()
{
var processInstaller = new ServiceProcessInstaller();
var serviceInstaller = new ServiceInstaller();
//set the privileges
    processInstaller.Account = ServiceAccount.LocalSystem;
    serviceInstaller.DisplayName = "My Service";
    serviceInstaller.StartType = ServiceStartMode.Manual;
//must be the same as what was set in Program's constructor
    serviceInstaller.ServiceName = "My Service";
this.Installers.Add(processInstaller);
this.Installers.Add(serviceInstaller);
}
}

This is pretty much the bare minimum when it comes to service options. We have to create a ServiceProcessInstaller and a ServiceInstaller. These two classes are responsible for installing the service. The ServiceProcessInstaller installs information common to all services, and the ServiceInstaller installs information for this specific service.

The Account property sets which privileges you'd like the service to run under. The default is User, but then we'd have to specify a username and a password to determine the account. I chose LocalSystem, which gives the service a lot (probably too much) access to the local computer.

Services are identified by name, so you have to ensure serviceInstaller.ServiceName is exactly the same as what you set in the constructor of Program. The rest of the options are pretty obvious. All that's left is to add our two installers to the Installers collection.

We're done! All that's left to do now is install the service.

Installing The Service

Services are installed using a tool from Microsoft called installutil.exe. This tool is free and is probably already on your computer. I doubt it's in your system path, so you might want to do a quick search for it and add it to your environment variables before continuing.

All you have to do to install your service is open a command prompt, cd to your Release directory, and type:

installutil MyWindowsService.exe

installutil output

Your service is now installed and ready to go. If you bring up your services manager, you should see one labeled "My Service". Of course, if you start it, nothing will happen since we didn't actually put any code in the OnStart function.

Windows Service List

If you want to uninstall the service, you can do so with the same utility but with the "-u" flag.

installutil -u MyWindowsService.exe

There's a lot of power that we haven't even touched in Windows Services, but this tutorial should hopefully give you a starting point on which you can expand and build some much more complex solutions. All of the example code has been attached as a Visual Studio 2008 solution.

Source:http://www.switchonthecode.com

Subscribe
Posted in Labels: , kick it on DotNetKicks.com |

4 comments:

  1. Anonymous Says:

    It is extremely interesting for me to read the blog. Thanx for it. I like such themes and everything that is connected to them. I definitely want to read a bit more soon.

  2. Anonymous Says:

    BTW, buy GPS blocker to disable all secret devices in your room or at work.

  3. Unknown Says:

    Thank you for an article, it was really helpful for a newbie like me.

    I am new to c# and would be great if i can get some more help on this issue i have.

    I am creating a simple service to run an SQL query and store result in some text file somewhere in the local machine. have added code to run connect to sql server in onstart().

    But when i try to start the service it stops immediately without any messages.

  4. Unknown Says:

    This is awesome!! really helpful for me. Thanks for sharing with us. Following links also helped me to complete my task.

    http://www.mindstick.com/Articles/e91aa075-0e62-4b05-8498-148c936bc370/?Windows%20Service%20in%20Net

    http://msdn.microsoft.com/en-us/library/d56de412(v=vs.80).aspx