Click here to Skip to main content
15,885,880 members
Articles / Programming Languages / C#

ChoServiceHost - Simplified Windows Service development

Rate me:
Please Sign up or sign in to vote.
1.17/5 (5 votes)
24 Feb 2010CPOL10 min read 22.8K   8   11
Develop and use Windows Service Application in a minute...

Introduction  

In this article, I would like to bring you a Windows Service Hosting application aka ChoServiceHost. It simplifies the development of windows service application. No need to worry about all the house keeping works required to create, setup and run the windows services.

There are plenty of articles and samples on the internet on how to write one and install them. Please see the below articles for quick start of developing Windows Service applications

http://blogs.msdn.com/bclteam/archive/2005/03/15/396428.aspx 

http://www.codeproject.com/KB/dotnet/simplewindowsservice.aspx

But all them requires the below basic steps in order to create a new Windows Service application

  • Creating a ServiceBase
  • Creating an Installer
  • Installing your new service
  • Starting the service
  • Most of all, Installing service on a specific account would require you either harcode them in the code or while installing you have input them interactively.

ChoServiceHost application bundled and abstracted all these steps for you. All you have to do is to create a project from 'ChoServiceHost Project' template, overrides few methods like OnStart / OnStop service events and and drop the assembly to 'ChoServiceHost' folder. That's it, your service is ready to use. 

PS: Please turn on Reflection Permission in order to use this application.

How to Create Windows Service with ChoServiceHost in a snap... 

  • Download and extract ChoServiceHostSetup.zip file. 
  • Run ChoServiceHostSetup.msi file. This will install the ChoServiceHost, Visual Studio templates into your machine. 
  • Open VS.NET 2008, Create a new project from 'ChoServiceHost Project' template as shown below 
  • It will create a new project with necessary references, classes for you.  
  •  
  • Add your business logics or override appropriate members, build the solution.
  • Now your Windows service application is ready to use.  
  • Goto binary folder, you can install and run your service by running ChoServiceHost.exe file using the following command line arguments.  
    • /i - To install the Windows Service 
    • /u - To uninstall the Windows Service 
    • /c - To run your service in console mode. 
    • /g - To generate key/vector values for encryption (used for password encryption, will talk about it later). 
    • /e value - To encrypt the passed value and display it on the console.  
    • /d value - To decrypt the passed value and display it on the console.

1. Additional information when you implement your service class 

  • ChoServiceApplicationAttribute exposes the below members to control the service parameters. These values used by ChoServiceHost while installing the service.
  • ServiceName - Windows Service Name
  • ServiceDisplayName - Windows Service Display Name
  • ServiceDescription - Short description about Windows Service
  • ServiceStartMode - Automatic/Manual/Disabled
  • ServiceAccount - It could have one these values LocalService/NetworkService/LocalSystem/User.
  • UserName - UserName of Windows account, when you want to run your service under specific user account. This value will be ignored when ServiceAccount is not specified as User.
  • EncryptedPassword - User's password in encrypted form. Please refer next section on how to generate encrypted password. This value will be ignored when ServiceAccount is not specified as User.
  • Also you class must derive from ChoServiceBase, override the nessasary methods. ChoServiceBase exposes the below overrides
    • OnStart - This method called when the Start command sent to the service by SCM or when the OS starts. Usually all the initialization tasks/code should be done here.ation tasks/code should be done here.
    • OnStop - This method called when the Stop command sent to the service by SCM. Usually all the cleanup tasks/code should done here.
    • OnContinue - This method called when the Continue command to the service by SCM.
    • OnPause - This method called when the Pause command to the service by SCM.
    • OnShutdown - This method called when the system is shutting down.
    • OnSessionChange - This method executed when a change event is received from a Terminal Server session.
    • OnPowerEvent - This method executed when the computer's power status has changed.
    • OnCustomCommand - This method called when SCM passes a custom command to the service.
    • Please check MSDN for System.ServiceProcess.ServiceBase for detailed information about the above commands. 

2. How you can control your Windows Service through configuration

After you create the service assembly, literally you can control most of Windows service parameters through configuration. As you know that you can input most of the service level parameters using ChoServiceApplicationAttribute with your class while developing the service. But those values can be overriden and confgured through configuration. In this section, I'll give you brief overview of how to control the windows service through configuration

a. choCommon/applicationSettings

This is the application level settings, In this configuration section, you can specify two parameters

  • applicationName - If you are developing and running multiple Windows services using ChoServiceHost.exe, you may want to distinguish them by specifying custom applicattionName. The log files are created by this name. If you dont specifiy this attribute, executable name (ChoServiceHost) will be used.
  • eventLogSourceName - This value will be used for posting any messages to the eventlog as the source. If not specified, it uses the applicationName as default value.

b. choCommon/AESCryptoSettings

When you want to run your service under specific user account, you may want protect user's password. This section used for encrypting and decrypting passwords while specifying the service to be run under specific account. Encryption module uses RijndaelManaged symmetric encryption algorithm. In this configuration section, you can specify two parameters

  • key - The secret key to be used for the symmetric algorithm
  • vector - The IV to be used for the symmetric algorithm.

Do you wonder how to get these values and specified in the configuration section? You can use ChoServiceHost.exe with /g flag. It produces the below in the console as well as in the log file...

2/21/2010 11:23:10 PM, Key: 219097248046007185203210119148228050029042131069242155018049049059100240245094203056187040129069
2/21/2010 11:23:10 PM, Vector: 157038063249122133219020243085077186149245194139
2/21/2010 11:23:10 PM, 
 
2/21/2010 11:23:10 PM, Please copy and paste the below Configuration Entry...
2/21/2010 11:23:10 PM, 
 
2/21/2010 11:23:10 PM, <AESCryptoSettings 
    type="Cinchoo.Core.Security.Cryptography.ChoAESCryptoGraphySettings, Cinchoo.Core" 
key="219097248046007185203210119148228050029042131069242155018049049059100240245094203056187040129069"
    vector="157038063249122133219020243085077186149245194139" />

Copy and paste just XML portion to the ChoServiceHost.exe.config file. Now you set the public encryption key in the application. Next you want to encrypt the password by running 'ChoServiceHost /e SomePassword'. This will output values to console as well as log file as below

2/21/2010 11:29:09 PM, Encrypt: SomePassword => 133204048034017206003220050187207208061110033184

Copy and paste just value after => symbol, no spaces, to either ChoServiceApplicationAttribute as below or you can configured in the configuration file as in mentioned in the next section.

 1 [ChoServiceApplication("TestService",
     ServiceDescription="Test Windows Service", UserName=".\XXX",
     EncryptedPassword="133204048034017206003220050187207208061110033184")]
 2 public class SampleService : ChoServiceBase
 3 {
 4     public override void OnStart(ChoServiceHostService serviceBase, string[] args)
 5     {
 6         //Do you initialization code here....
 7         Console.WriteLine("OnStart");
 8         Trace.WriteLineIf(true, "OnStart");
 9         base.OnStart(serviceBase, args);
10     }
11
12     public override void OnStop(ChoServiceHostService serviceBase)
13     {
14         //Do your cleanup code here...
15         Console.WriteLine("OnStop");
16         Trace.WriteLineIf(true, "OnStop");
17         base.OnStop(serviceBase);
18     }
19 }

c. choServiceHost/installerSettings

This is the section where you can configure service level atributes. These values overrides any values specified in the ChoServiceApplicationAttribute when you implement your class. 

  • serviceName - Windows Service Name 
  • serviceDisplayName - Windows Service Display Name
  • serviceDescription - Short description about Windows Service
  • serviceStartMode - Automatic/Manual/Disabled
  • serviceAccountInfo/serviceAccount - It could have one these values LocalService/NetworkService/LocalSystem/User.
  • serviceAccountInfo/userName - UserName of Windows account, when you want to run your service under specific user account. This value will be ignored when ServiceAccount is not specified as User.
  • serviceAccountInfo/encryptedPassword - User's password in encrypted form. Please refer the above section on how to generate encrypted password. This value will be ignored when ServiceAccount is not specified as User.

Normally ChoServiceHost discover Service Assembly in their folder/sub-folders and use them by default. But in some situations (you have a service assembly or multiple service assemblies having classes decorated with ChoServiceApplicationAttribute), you may want specify them explicitly. You can do installerSettings/serviceApplicationType element as below

<installerSettings type="Cinchoo.Core.ServiceHost.Settings.ChoServiceHostInstallerSettings, Cinchoo.Core.ServiceHost">
  serviceName="TestService" serviceDisplayName="TestServiceDisplayName" serviceDescription="Test Service Description" 
                   serviceStartMode="Automatic" >
  <serviceAccountInfo serviceAccount="User" userName="xxx" password="12708216311714802120002721920614921505906" />
   <!--You can specify explicitly the type of the service implementation assmebly,
   otherwise ServiceHost will discover one from its bin directory/sub-directories for one.--> 
  <serviceApplicationType>TestServiceApplication.SampleService, TestServiceApplication</serviceApplicationType>
</installerSettings>

d. choServiceHost/settings

Somtime you may want to control the ServiceBase settings through configuration. It is highly unlikely you will configure. In case you want, please read this section. 

  • autoLog - Indicates whether to report Start, Stop, Pause, and Continue commands in the event log. 
  • canHandlePowerEvent - A value indicating whether the service can handle notifications of computer power status changes.
  • canHandleSessionChangeEvent - A value that indicates whether the service can handle session change events received from a Terminal Server session.
  • canPauseAndContinue - A value indicating whether the service can be paused and resumed.
  • canShutdown - A value indicating whether the service should be notified when the system is shutting down.
  • canStop - A value indicating whether the service can be stopped once it has started.
  • ExitCode - The exit code for the service.
  • canRaiseEvents - A value indicating whether the component can raise an event.

Please visit MSDN for System.ServiceProcess.ServiceBase to get more information on the above members. 

3. Log files

ChoServiceHost produces two log files along other than writing messages event log.

  • Log - Log files are created under this folder. These log files are rolled and created new each time the service gets re-started. Use System.Diagnostics.Trace class for writing your debug messages to this log file. You can control the output of these messages by adding the below configuration section in ChoServiceHost.exe.config file. Please visit http://msdn.microsoft.com/en-us/library/system.diagnostics.traceswitch.aspx link for more information.
<!-- Trace Settings -->
<system.diagnostics>
  <switches>
    <add name="ChoSwitch" value="4" />
  </switches>
</system.diagnostics>
  • InstallerLog - Log files are created under this folder when you install and uninstall the service. These log files are rolled and created new each time the service gets re-installed. User System.Diagnostics.Trace class to write your debug message to this log file. Whatever you write from IChoServiceProcessInstaller interface overrides will be routed to this log file.For controlling of the output of these message, you need to edit/create InstallUntil.exe.config file, add the above same configuration section.

PS: I'll put a fix on ChoServiceHost to use System.diagnostcs section in ChoServiceHost.exe.config for controlling the output of the InstallerLog debug messages.

4. Subscribe to ServiceProcess Installation events (For advanced users)

For developers who would like to subscribe to ServiceProcess installtion events and to carry out some custom actions, you can do so by deriving you class from IChoServiceProcessInstaller interface.

IChoServiceProcessInstaller interface exposes the below members 

  • OnCommitting - Method called before the installers in the System.Configuration.Install.Installer.Installers property committ their installations.
  • OnCommitted - Method called after all the installers in the System.Configuration.Install.Installer.Installers property have committed their installations.
  • OnBeforeUninstall - Method called before the installers in the System.Configuration.Install.Installer.Installers property perform their uninstall operations.
  • OnBeforeRollback - Method called before the installers in the System.Configuration.Install.Installer.Installers property are rolled back.
  • OnBeforeInstall - Method called before the System.Configuration.Install.Installer.Install method of each installer in the installer collection has run.
  • OnAfterUninstall - Method called after all the installers in the System.Configuration.Install.Installer.Installers property perform their uninstallation operations.
  • OnAfterRollback - Method called after the installations of all the installers in the System.Configuration.Install.Installer.Installers property are rolled back.
  • OnAfterInstall - Method called after the System.Configuration.Install.Installer.Install methods of all the installers in the System.Configuration.Install.Installer.Installers property have run.

Please visit MSDN for System.ServiceProcess.Installer to get more detailed information for the above methods. 

Below is the code snippet of implemented IChoServiceProcessInstaller interface 

 1 [ChoServiceApplication("TestService", ServiceDescription="Test Windows Service",
       ServiceStartMode=ServiceStartMode.Automatic)]
 2 public class SampleService : ChoServiceBase, IChoServiceProcessInstaller
 3 {
 4     public override void OnStart(ChoServiceHostService serviceBase, string[] args)
 5     {
 6         //Do you initialization code here....
 7         Console.WriteLine("OnStart");
 8         Trace.WriteLineIf(true, "OnStart");
 9         base.OnStart(serviceBase, args);
10     }
11
12     public override void OnStop(ChoServiceHostService serviceBase)
13     {
14         //Do your cleanup code here...
15         Console.WriteLine("OnStop");
16         Trace.WriteLineIf(true, "OnStop");
17         base.OnStop(serviceBase);
18     }
19
20     #region IChoServiceProcessInstaller Members
21
22     public void OnCommitting(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
23     {
24         Trace.WriteLineIf(true, "OnCommitting");
25     }
26
27     public void OnCommitted(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
28     {
29         Trace.WriteLineIf(true, "OnCommitted");
30     }
31
32     public void OnBeforeUninstall(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
33     {
34         Trace.WriteLineIf(true, "OnBeforeUninstall");
35     }
36
37     public void OnBeforeRollback(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
38     {
39         Trace.WriteLineIf(true, "OnBeforeRollback");
40     }
41
42     public void OnBeforeInstall(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
43     {
44         Trace.WriteLineIf(true, "OnBeforeInstall");
45     }
46
47     public void OnAfterUninstall(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
48     {
49         Trace.WriteLineIf(true, "OnAfterUninstall");
50     }
51
52     public void OnAfterRollback(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
53     {
54         Trace.WriteLineIf(true, "OnAfterRollback");
55     }
56
57     public void OnAfterInstall(ServiceProcessInstaller serviceProcessInstaller,
           System.Configuration.Install.InstallEventArgs e)
58     {
59         Trace.WriteLineIf(true, "OnAfterInstall");
60     }
61
62     #endregion
63 }

That's all folks. Try it, please do drop your feedback. 

Updated

ChoServiceHost binary and source files are updated with the below fixes. 

  • Added volatile keyword to ChoSingleton._instance member. 
  • There was a glitch in log files generation by Service Installer. Addressed the issue. Now the ChoServiceHost produces the number of log folders based on the run mode 
  • ConsoleLog - Log files are created under this folder when you run ChoServiceHost in console mode (ChoServiceHost.exe /c). 
  • InstallServiceLog - Log files are created under this folder when you install the service (ChoServiceHost.exe /i). 
  • ServiceInstallerLog - Log files are created under this folder by Windows Service Installer (Whatever traces written from IChoServiceProcessInstaller overrides). 
  • ServiceLog - Log files are created under this folder when the Service gets started successfully (Whatever traces written from ChoServiceBase overrides). 
  • UninstallServiceLog - Log files are created under this folder when you uninstall the service (ChoServiceHost.exe /u). 
  • Still to come:

  • Multiple service host assemblies hosted and run in one process (different AppDomains though) 
  • Adding recovery options to Windows Service
  • Adding Dependency services to your Windows Service application 
  • more 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



Comments and Discussions

 
GeneralSingelton and multicore Pin
solo23-Feb-10 11:38
solo23-Feb-10 11:38 
GeneralRe: Singelton and multicore Pin
User 112731723-Feb-10 12:31
User 112731723-Feb-10 12:31 
GeneralMy vote of 1 Pin
Md. Marufuzzaman21-Feb-10 17:52
professionalMd. Marufuzzaman21-Feb-10 17:52 
GeneralMy vote of 1 Pin
gaurav_verma_mca21-Feb-10 17:47
gaurav_verma_mca21-Feb-10 17:47 
GeneralRe: My vote of 1 Pin
User 112731721-Feb-10 19:36
User 112731721-Feb-10 19:36 
GeneralMy vote of 1 Pin
Not Active21-Feb-10 9:40
mentorNot Active21-Feb-10 9:40 
GeneralRe: My vote of 1 Pin
User 112731721-Feb-10 19:35
User 112731721-Feb-10 19:35 
GeneralMy vote of 1 Pin
Dave Kreskowiak20-Feb-10 9:58
mveDave Kreskowiak20-Feb-10 9:58 
GeneralRe: My vote of 1 Pin
User 112731721-Feb-10 19:32
User 112731721-Feb-10 19:32 
GeneralMy vote of 2 Pin
Trollslayer20-Feb-10 9:53
mentorTrollslayer20-Feb-10 9:53 
GeneralRe: My vote of 2 Pin
User 112731721-Feb-10 19:30
User 112731721-Feb-10 19:30 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.