Creating a Windows Service

Creating a Windows Service in .NET requires using several .NET classes, which provide the necessary interface to the operating system required by a Windows Service.

The .NET Framework Classes for Windows Services

Several base classes are needed to create a Windows Service:

  • System.ServiceProcess.ServiceBase—Provides the base class for the Windows Service. The class containing the logic that will run in the service inherits from ServiceBase. A single executable can contain more than one service, but each service in the executable is a separate class that inherits from ServiceBase.
  • System.Configuration.Install.Installer—This is a generic class that performs the installation chores for a variety of components. One class in a Windows Service process must inherit and extend Installer in order to provide the interface necessary to install the service under the various Windows operating systems.

Each class that inherits from Installer needs to contain an instance of each of the following classes:

  • System.ServiceProcess.ServiceProcessInstaller—This class contains the information needed to install a .NET executable that contains Windows Services (that is, an executable that contains classes that inherit from ServiceBase). The .NET installation utility for Windows Services (InstallUtil.exe, discussed later) calls this class to get the information it needs to perform the installation.
  • System.ServiceProcess.ServiceInstaller—This class also interacts with the InstallUtil.exe installation program. Whereas ServiceProcessInstaller contains information needed to install the executable as a whole, ServiceInstaller contains information about a specific service in the executable. If an executable contains more than one service, then an instance of ServiceInstaller is needed for each one.

For most Windows Services you develop, you can let Visual Studio take care of Installer, ServiceProcessInstaller, and ServiceInstaller. You just need to set a few properties. The class you should thoroughly understand is ServiceBase, as this is the class that contains the essential functionality of a Windows Service.

The ServiceBase Class

The ServiceBase class contains several useful properties and methods, but initially it is more important to understand the methods that are fired by the Service Control Manager when the state of the service is changed. Table 16.1 describes the most important of these methods.

Table 16.1 Important ServiceBase Events

Event Description
OnStart Occurs when the service is started. This is where the initialization logic for a service is usually placed.
OnStop Occurs when the service is stopped. Cleanup and shutdown logic are generally placed here.
OnPause Occurs when the service is paused. Any logic required to suspend operations during a pause goes here.
OnContinue Occurs when a service continues after being paused.
OnShutdown Occurs when the operating system is being shut down.
OnSessionChange Occurs when a change event is received from a Terminal Session service. This method was new in .NET Framework 2.0.
OnPowerEvent Occurs when the system's power management software causes a change in the power status of the system. This is typically used to change the behavior of a service when a system is entering or leaving a “suspended” power mode. This is more frequent with end users who are working on laptops.
OnCustomCommand Occurs when an external program has told the Service Control Manager that it wants to send a command to the service. The operation of this event is covered in the section “Communicating with the Service.”

The events used most frequently are OnStart, OnStop, and OnCustomCommand. The OnStart and OnStop events are used in almost every Windows service written in Visual Basic, and the OnCustomCommand is used when any special configuration of the service is needed while the service is running.

All of these are Protected events, so they are available only to classes that inherit from the ServiceBase class. Because of the restricted context in which it runs, a Windows Service component that inherits from ServiceBase often lacks a public interface. While you can add public properties and methods to such a component, they are of limited use, because programs running in a normal user context cannot obtain an object reference to running a Windows Service component, which is running in a special system context created by the System Control Manager.

To be active as a Windows Service, an instance of the ServiceBase class must be started via the shared Run method of the ServiceBase class. However, normally you don't have to write code to do this because the template code generated by a Visual Studio Windows Service project places the correct code in the Main subroutine of the project for you.

The most commonly used property of the ServiceBase class is the AutoLog property. This Boolean property is set to True by default. If True, then the Windows service automatically logs the Start, Stop, Pause, and Continue events to an event log. The event log used is the Application Event Log and the Source in the log entries is taken from the name of the Windows service. This automatic event logging is stopped by setting the AutoLog property to False.

Later in this chapter you will create a File Watcher example that will go into more detail about the automatic logging capabilities in a Windows service, and about event logs in general.

Installation-Oriented Classes

The Installer, ServiceProcessInstaller, and ServiceInstaller classes are quite simple to build and use if you are employing Visual Studio. After you create your Windows Service project, Visual Studio will create a class file called Service1.vb for you. To add the Installer, ServiceProcessInstaller, and ServiceInstaller classes to your project, simply right-click the design surface of this ServiceBase class, Service1.vb, and select Add Installer. This creates the code framework necessary to use them.

The Installer class (named ProjectInstaller.vb by default in a Windows Service project) generally needs no interaction at all — it is ready to use when created by Visual Studio. However, it may be appropriate to change some properties of the ServiceProcessInstaller and ServiceInstaller classes. You can do this by simply highlighting these objects on the design surface and changing their properties directly in the Properties window of Visual Studio. The properties that are typically modified for ServiceProcessInstaller include the following:

  • Account—This specifies the type of account under which the entire service application will run. Different settings give the services in the application different levels of privilege on the local system. For simplicity, this chapter uses the highest level of privilege, LocalSystem, for most of the examples. If this property is set to User (which is the default), then you must supply a username and password when the service is installed. (You'll see more about that when InstallUtil.exe is discussed later in the chapter.) That user's account is used to determine privileges for the service. If there is any possibility that a service could access system resources that should be “out of bounds,” then using the User setting to restrict privileges is a good idea. Besides LocalSystem and User, other possible settings for the Account property include NetworkService and LocalService.
  • HelpText—This specifies information about the service that will be displayed in certain installation options.

If the Account property is set to User, then it is good practice to set up a special user account for the service, rather than rely on some existing account intended for a live user. The special account can be set up with exactly the appropriate privileges for the service. This way, it is not as vulnerable to having its password or its privileges inadvertently changed in a way that would cause problems in running the service.

For the ServiceInstaller class, the properties you might change include the following:

  • DisplayName—The name of the service displayed in the Service Manager or the Server Explorer can be different from the class name and the executable name if desired, though it is better to make this name the same as the class name for the service.
  • StartType—This specifies how the service is started. The default is Manual, which means you must start the service yourself, as it will not start automatically after the system boots. If you want the service to always start when the system starts, then change this property to Automatic. The Service Manager can be used to override the StartType setting.
  • ServiceName—The name of the service that this ServiceInstaller handles during installation. If you changed the class name of the service after using the Add Installer option, then you would need to change this property to correspond to the new name for the service.

ServiceProcessInstaller and ServiceInstaller are used as necessary during the installation process, so there is no need to understand or manipulate the methods of these.

Multiple Services within One Executable

It is possible to place more than one class that inherits from the ServiceBase class in a single Windows Service executable. Each such class then allows for a separate service that can be started, stopped, and so on, independently of the other services in the executable.

If a Windows Service executable contains more than one service, then it must contain one ServiceInstaller for each service. Each ServiceInstaller is configured with the information used for its associated service, such as the displayed name and the start type (automatic or manual). However, the executable still needs only one ServiceProcessInstaller, which works for all the services in the executable. It is configured with the account information that is used for all the services in the executable.

The ServiceController Class

Another important .NET Framework class used with Windows Services is System.ServiceProcess.ServiceController. This class is not used when constructing a service; it is used by external applications to communicate with a running service, enabling operations such as starting and stopping the service. The ServiceController class is described in detail in the section “Communicating with the Service.”

Other Types of Windows Services

The ServiceBase and ServiceController classes can be used to create typical Windows Services that work with high-level system resources such as the file system or performance counters. However, some Windows Services need to interact at a deeper level. For example, a service may work at the kernel level, fulfilling functions such as that of a device driver.

Presently, the .NET Framework classes for Windows Services cannot be used to create such lower-level services, which rules out both Visual Basic and C# as tools to create them. C++ is typically the tool of choice for these types of services. If the C++ is used, the code for such services would typically run in unmanaged mode.

Another type of service that cannot be created with the .NET Framework classes is one that interacts with the Windows desktop. Again, C++ is the preferred tool for such services.

You'll look at the types of services that are possible during the discussion of the ServiceType property of the ServiceController class, in the section “Communicating with the Service.”

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset