A Windows Service without a template
Written by Harry Fairhead   
Friday, 14 August 2009
Article Index
A Windows Service without a template
A simple service
Using Timers
Event log service
Other logs

 

Time to get started.

Create a new application using C# Express or any other .NET IDE, the changes needed to use VB or any other .NET language are trivial.

The easiest thing to do is to use the Empty Project template and call the project SimpleService.

Next add a CodeFile to the project called SimpleServer. Creating the service is very easy indeed but we need to make use of some unusual parts of the framework class library.

Add a reference (Project,Add Reference) to: System and System.ServiceProcess and

using System;
using System.ServiceProcess;

to the start of the program.

The service is, as already explained, implemented as a class that inherits from ServiceBase. Its constructor is called when the service is created and so consists of a few statements that set some fairly obvious standard properties:

public class SimpleServer 
: ServiceBase
{
public SimpleServer()
{
this.ServiceName = "SimpleServer";
this.CanStop = true;
this.CanPauseAndContinue = false;
this.AutoLog = true;
}

The real work of the service is done by the OnStart and OnStop event handlers which are called, as you might guess, when the service is started and stopped by the Service Control Manager (SCM). Exactly how all this fits together will become clear as the example progresses.

protected override 
void OnStart(string[] args)
{
// do startup stuff
}
protected override void OnStop()
{
// do shutdown stuff
}

The only other method that the class needs is Main which is the default startup point of any console program. In this case Main simply creates an instance of the service class:

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

That’s all there is to the Windows service but we also need an installer to set up the registry entries needed to make the system aware of your new service.You could do this manually, or write a custom script for it, but the .NET framework provides a standard way of doing the job. The first part of the installation mechanism is to create an instance of the Installer class. This has to be marked as a class to instantiate during installation by the use of the RunInstaller attribute:

[RunInstaller(true)]
public class SimpleService : Installer

The only method you need to implement is the constructor and this simply sets some easy to understand properties and creates two installer objects:

 private ServiceProcessInstaller 
processInstaller;
private ServiceInstaller
serviceInstaller;
public SimpleService()
{
processInstaller =
new ServiceProcessInstaller();
serviceInstaller =
new ServiceInstaller();
processInstaller.Account =
ServiceAccount.LocalSystem;
serviceInstaller.StartType =
ServiceStartMode.Manual;
serviceInstaller.ServiceName =
"SimpleService";
Installers.Add(serviceInstaller);
Installers.Add(processInstaller);
}
}

The three essential properties that you have to define are the account to use to run the service, how and when it should be started – automatic or manual – and its name.

Usually the LocalSystem account has enough privileges for a service but you can supply a user name and password with custom permissions.

You also need to add a reference to System.Configuration.Install and add two using instructions to the start of the program:

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

Now we have all the code needed to create and install the service and we can try it out.

First we need to build the project to create an executable in the Release folder – there is nothing to be gained or learned from running the application in Visual Studio under the debugger as it has to be run as a service.

Next we need to find the InstallUtil.exe program, open a command console and enter:

Path dir that InstallUtil is stored in

Check that the path command has worked by entering:

InstallUtil

which should result in a help screen explaining how to use the command. Finally try the command:

InstallUtil /LogToConsole=true 
SimpleServer\bin\
Release\SimpleServer.exe"

where you supply the directory path to SimpleServer.exe.

You should see a lot of messages that tell you that your service has been correctly installed.

To check that it has worked, and to gain some familiarity with the Services tool, open the Control Panel, Administrative Tools and finally Services. Scroll down and you should find a new service called SimpleService in the list.

You can use the tool to start and stop your service and modify it in other ways. If your service isn’t listed then it hasn’t been installed and you need to pay attention to the messages that InstallUtil generated.

Once you have installed a service you can modify it simply by editing the code and building the project. This updates the EXE file stored in the release directory. To see the changes in action you simply restart the service. For example, we can popup a message box to indicate when the service is starting.

Change the OnStart event handler to read:

protected override void OnStart(
string[] args)
{
MessageBox.Show(
"SimpleService has started",
"SimpleService",
MessageBoxButtons.OK,
MessageBoxIcon.Information,
MessageBoxDefaultButton.Button1,
MessageBoxOptions.ServiceNotification);
}

You also need to add a reference to System.Windows.Forms to the start of the program:

using System.Windows.Forms;

If you build the project and use the Services tool to start the service you should see the message box appear.

 

This special ServiceNotification message box is the only sort of user interface available to a basic service. You need to keep in mind that it will be displayed even if no user is logged on and only one such message box is displayed at any given time – additional message boxes are queued and appear when the first one is dismissed.

You can give a service a full user interface using Windows Forms but to do so you need to set AllowServiceToInteractWithDesktop. In this case you have to be careful to check that there is a user to interact with and there are serious security problems with this type of service.

If you find that you need a service with a user interface of this sort you should seriously consider the whether it is indeed a service!

<ASIN:1590598849>

<ASIN:0321485890>

<ASIN:1590599543>



Last Updated ( Friday, 14 August 2009 )