With the .NET Framework, it is much easier to develop applications that run as
Windows Services using classes defined in the System.ServiceProcess namespace.
This article starts with an overview of the ServiceProcess namespace and the
classes you are most likely to use in developing your own services. Next, we'll
look at an developing an example using Visual Studio.NET. Finally, we'll cover
the installation of your service.
System.ServiceProcess Namespace
From the System.ServiceProcess namespace, there is one key base class in
developing services, two used in deploying services, and one key class used for
managing services. They are:
ServiceBase
- this is the base class for Windows Services. Your class will derive directly
or indirectly from this class. For your service to be useful, you'll override
the OnStart, OnPause, and OnStop methods.
ServiceProcessInstaller
- this class is involved in installing your service with the Service Control
Manager, and does work common to all services in an executable such as writing
registry values associated with your services. You will need one instance of
this class per application.
ServiceInstaller
- this class is also involved in installying your service, and writes registry
information for a particular service. You need a separate ServiceInstaller for
each service in your application.
ServiceController
- this class gives you programmatic access for connecting to a service,
manipulating it, and get information about it. Using this class, you can start
or stop services from a custom application.
Creating a Windows Service
To create a Windows Service in Visual Studio.NET, create a New Project and
select the Windows Service project type in the New Project dialog. Visual
Studio will create a skeleton service for you called Service1, derived from
ServiceBase. When the process is complete, Visual Studio will be loaded with
your service in Design View.
Next, click on the link that says "click here to switch to code view", or right
click in design view and select View Code from the context menu. Find the
OnStart method, which is called when your service is started. Here is where you
would add your custom logic. For our example, we are going to leave the service
as is, since by default the service will write to the Event Log whenever it is
started or stopped. That will be enough to verify that our service is working.
Below is the code for our service.
There are three things to note. First is the constructor, where you can add
your custom initialization code. Next is the OnStart and OnStop methods, which
is where you can add your custom service behavior. Third is the Main method. In
order to run your service, this method must pass an instance of your method to
the ServiceBase.Run static method.
using
System; using
System.Collections; using
System.ComponentModel; using
System.Data; using
System.Diagnostics; using
System.ServiceProcess;
public
Service1() { // This call is required by the Windows.Forms Component Designer.
InitializeComponent();
// TODO: Add any initialization after the InitComponent call
}
// The main entry point for the process
staticvoid
Main() { // More than one user Service may run within the same process. To add
// another service to this process, change the following line to
// create a second service object. For example,
// ServicesToRun = New System.ServiceProcess.ServiceBase[] {new Service1(), new MySecondUserService()};
protectedoverridevoid
OnStart(string[]args) { // TODO: Add code here to start your service.
}
protectedoverridevoid
OnStop() { // TODO: Add code here to perform any tear-down necessary to stop your service.
} } }
Adding a Windows Service Installer
Once you have the code for your service ready, return to Design mode, right
click, and select Properties. Change the name property if you want, which is
the name of your class. Next, change the ServiceName property, which is the
name used when displaying your service in the Service Control Manager, and used
to identify your service by the Installers.
Note: If you change the name of your class, you may also need to change it in
the Main() method of your service. Visual Studio does not automatically update
the service name. Look for a line like the following, and change Service1 to
the new name of your service class.
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new
Service1() };
Next we'll add the necessary Installers for our service. At the bottom of the
Properties menu, you will see a link for Add Installer. By clicking this,
Visual Studio will do some work and will finish in Design mode for a new file,
ProjectInstaller.cs. You'll notice the class contains a
ServiceProcessInstaller, and a ServiceInstaller. Right click in the design pane
and select View Code to see the code in this file.
Visual Studio has created a ProjectInstaller class deriving from
System.Configuration.Install.Installer, which contains an instance of a
ServiceProcessInstaller and a ServiceInstaller. Expand the "Component Designer
generated code" to see that these two components have been added to the
Installers collection. This will ensure that our installer classes are called
to install our service when we use the InstallUtil.exe command line utility.
Return to Design mode for the ProjectInstaller class. Right click on the
serviceProcessInstaller1 icon, and select Properties. In the properties window,
change the Account property to LocalSystem. This is who the service is set to
run as when you install your service. If you leave it as User, the install
program will prompt you for a username and password. Setting this value to
LocalSystem will make installation a little easier, since we will not have to
indicate a specific user account under which to run the service.
Build your project, and now you are ready for deployment.
Installing the Service
To install your service, you first need to Build it from Visual Studio.NET.
This will create an .exe file in the bin/debug directory. Next, you need to use
the InstallUtil.exe command line utility. The syntax for this utility is as
follows:
InstallUtil.exe [ServiceExeFile]
Open a command console and navigate to the bin/debug directory under your
Visual Studio.NET project. Once there, run InstallUtil using the syntax above.
In our example, we'll run:
InstallUtil DotnetCodersMailService.exe
The following screen show shows you what you can expect for output if the
installation was successful:
Managing the Service
Once your service is installed, you can control it from the Windows Services
ControlManager (Programs->AdministrativeTools->Services). The following
screenshot shows our service, and indicates that it is not currently started,
has to be started manually, and runs under the LocalSystem account.
You can also control your service programmatically with the ServiceController
class. This allows you to incorporate the tracking of and the changing of your
service's state (start, paused, stopped). Using this class will be covered in a
future article.
Click your service and select Start. Now, check your machine's Application
Event Log. You'll see an Information event noting that your service has
started!