Windows Services

Normally, a windows service is used to provide a system service to other applications, such as an antivirus service for example. The best practice for a business application providing a service would be to create a Windows Forms application, which runs on the desktop of a server. A user would be used to login to the server, start the application, and lock the server. At which point the application would provide a service to other systems. This is because a business application normally isn’t part of operating system infrastructure, while all windows services are.

For this project however, to try out technologies, Windows Services were used. And, I have to admit, after having tried it out, it brings more problems along then it solves. As you have to learn from experience, this was a valuable lesson for future similar projects.

To create a new Windows Service, a template can be used from Visual Studio when creating a new project. This provides a starting class, with the two most important methods, OnStart and OnStop. When you want to start or stop the service from Windows, these methods will be called.

However, these methods had to end in a reasonable time, being 30 seconds. Otherwise the service manager would give an error. It is possible the initialization of a service can take longer. To solve this, a Timer was added to the project, which had an interval of 10, was disabled and had a method listening for its Elapsed event. During the OnStart method, this timer simply was started, and nothing more. This caused the service to start immediately, while it had all the time it needed to perform its initialization inside the Elapsed event.

[csharp] protected override void OnStart(string[] args) { this.serviceTimer.Enabled = true; } [/csharp]

After this, the Windows Service could be coded just like you would code anything else. When everything was done, it was time to add an installer to install the service into the system. To do this, a new class had to be added to the project which had a RunInstaller attribute set to true, inherited from Installer and included the following using statements:

[csharp] using System; using System.ComponentModel; using System.ServiceProcess; using System.Configuration.Install;

namespace MediaService.Player { [RunInstaller(true)] public class PlayerServiceInstaller: Installer { [/csharp]

The installer itself had to be configured in the constructor, with the following code:

[csharp] private ServiceInstaller PlayerInstaller; private ServiceProcessInstaller PlayerProcessInstaller;

public PlayerServiceInstaller() { this.PlayerInstaller = new ServiceInstaller(); this.PlayerInstaller.StartType = ServiceStartMode.Manual; this.PlayerInstaller.ServiceName = "MediaServicePlayer"; this.PlayerInstaller.DisplayName = "MediaService - Media Player"; this.Installers.Add(this.PlayerInstaller);

this.PlayerProcessInstaller = new ServiceProcessInstaller(); this.PlayerProcessInstaller.Account = ServiceAccount.User; this.Installers.Add(this.PlayerProcessInstaller); } / PlayerServiceInstaller / [/csharp]

At this point, the Windows Service was ready to be installed. To do this, the installutil utility had to be used. This tool is available from the Visual Studio .NET 2003 Command Prompt and takes the service executable as a parameter.

During the installation, a log was be generated, and a dialog box appeared, allowing configuring the account the service had to run under. After this, the service was successfully installed and accessible from MMC.