CHAPTER 1
The first step in developing a Windows Service, after loading Microsoft Visual Studio, is to create a Windows Service type project. The following figure shows this kind of project dialog in Visual Studio.

The base line for a Windows Service project consists of two programs; one of them, called Program.cs, manages the application entry point. The other one, Service1.cs, encapsulates the service class definition. A developer can add as many programs as it needs in order to easily maintain code or to add special features to the project.
The project base line can be customized in order to fit a developer’s own needs. To do it in such way, you must rename the Solution, Project, Program.cs, and Service1.cs nodes. For the purposes of this book, the Windows Service project will be named monitorservice. The following figure shows the Visual Studio Solution Explorer before and after customization.

Tip: You can quickly rename elements in the Solution Explorer tree by right-clicking the desired node and applying the Rename command, from the Context pop-up menu. After you rename the action, the Visual Studio Refactoring Code Tool is fired.
Like many Visual Studio applications, a Windows Service needs an entry point in order to be executed. The following code sample shows the entry point for the project.
Code Sample 1
using System; using System.Collections.Generic; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks;
namespace monitorservice { static class monitorservicemain { /// <summary> /// The main entry point for the application. /// </summary> static void Main() { ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[] { new monitorservice() }; ServiceBase.Run(ServicesToRun); } } } |
This program creates an array named ServicesToRun. This array is based on the ServiceBase .NET class, and stores an instance of the monitorservice custom class. Monitorservice is also derived from the ServiceBase .NET class, and will manage the Windows Service that is being developed.
Once the array is created, the program calls the Run method of ServiceBase, passing the array as a parameter, and service execution starts.
This class is part of the System.ServiceProcess namespace, and provides a base class for a service that will exist as part of a service application. ServiceBase must be derived from creating a new service class for a service application. As mentioned previously, the derived class that will manage the service is named monitorservice, and can be found in the monitorservice.cs file.
Remarks
Any useful service overrides the OnStart and OnStop methods. For additional functionality, OnPause and OnContinue can be overridden with specific behavior in response to changes in the service state. This can be useful if a user interface needs to be provided to change service behavior, because the service can be notified about this change using these methods.
By default, services run under the System account, which is not the same as the Administrator account. The rights of the System account can’t be changed.
When a service is started, the system locates the executable and runs the OnStart method for that service, contained within the executable. However, running the service is not the same as running the executable. The executable only loads the service. The service is accessed (for example, started, and stopped) through the Service Control Manager.
The following code sample shows the monitorservice derived class definition.
Code Sample 2
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Diagnostics; using System.Linq; using System.ServiceProcess; using System.Text; using System.Threading.Tasks;
namespace monitorservice { public partial class monitorservice : ServiceBase { private System.Timers.Timer serviceTimer = null;
public monitorservice() { InitializeComponent(); }
protected override void OnStart(string[] args) { }
private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { }
protected override void OnStop() { }
} } |
When the project was created, Visual Studio generated this code automatically. Basically this code does the following:
This is the base code from which the entire service application will be developed. In order to add more features to the application, we may need to override other events. I suggest sticking to service lifetime, which is explained in the following section.
A service goes through several internal states in its lifetime. First, the service is installed onto the system on which it will run. This process executes the installers for the service project and loads the service into the Services Control Manager for that computer. The Services Control Manager is the utility provided to administer services.
After the service has been loaded, it must be started. Starting the service allows it to begin functioning. A service can be started from the Services Control Manager, from Server Explorer, or from code by calling the Start method. The Start method passes processing to the application's OnStart method and processes any code you have defined there.
A running service can exist in this state indefinitely until it is either stopped or paused, or until the computer shuts down. A service can exist in one of three basic states: Running, Paused, or Stopped. The service can also report the state of a pending command: ContinuePending, PausePending, StartPending, or StopPending. These statuses indicate that a command has been issued (such as a command to pause a running service), but has not yet been carried out. You can query the Status to determine what state a service is in, or use WaitForStatus to carry out an action when any of these states occurs.
You can pause, stop, or resume a service from the Services Control Manager, from Server Explorer, or by calling methods in code. Each of these actions can call an associated procedure in the service (OnStop, OnPause, or OnContinue), in which you can define additional processing to be performed when the service changes state.
When a service is started, the system locates the executable and runs the OnStart method for that service, contained within the executable. However, running the service is not the same as running the executable; the executable only loads the service. The service is accessed (for example, started and stopped) through the Service Control Manager.
The executable calls the ServiceBase derived class's constructor the first time Start is called on the service. The OnStart command-handling method is called immediately after the constructor executes. The constructor is not executed again after the first time the service has been loaded, so it is necessary to separate the processing performed by the constructor from that performed by OnStart. Any resources that can be released by OnStop should be created in OnStart, since creating resources in the constructor prevents them from being created properly if the service is started again after OnStop has released the resources.
The following code sample shows how the resources needed are created.
Code Sample 3
protected override void OnStart(string[] args) { this.serviceTimer = new System.Timers.Timer(300); this.serviceTimer.AutoReset = true; this.serviceTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.timer_Elapsed); this.serviceTimer.Start(); } |
In this case a Timer object is instantiated and started. Every 300 milliseconds, the Elapsed event of the timer will be fired and the timer_Elapsed method will be executed. The OnStop event will release this resource.
The OnStop method executes every time a Stop command is sent to the service, since the OnStop event is fired. The Stop command could be sent by the Service Control Manager (SCM). In similar way to the OnStart method, we can use the OnStop method to perform any task needed at service stopping, such as releasing resources no longer needed, as shown in the following code sample.
Code Sample 4
protected override void OnStop() { this.serviceTimer.Stop(); this.serviceTimer.Dispose(); this.serviceTimer = null; } |
This code stops the Timer object execution and disposes it before service execution stops.
Windows Services can be developed with .NET and Visual Studio using the Windows Service template provided for this purpose. This template automatically creates the code baseline for development.
The ServiceBase .NET class provides a base class for a service that will exist as part of a service application, and must be derived from creating a new service class for a service application.
When the service code baseline is created, the OnStart() and OnStop() methods are overridden in order to execute actions when the service starts or stops its execution.