Calendar

<<  mars 2010  >>
lumamejevesadi
22232425262728
1234567
891011121314
15161718192021
22232425262728
2930311234

View posts in large calendar
Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010

(septembre 25, 2008 08:55)

We have seen previously how to create and deploy a windows service (here and here using a separate installer DLL). What we have seen also is that we can control the start type of the service to specify whether it will be launched manually or automatically. This is very interesting, however this will be used internally by windows only at the next startup of the operating system.

It seems very logical that if we install a service and that we want it to start in an "automatic way", this service shall be running at the end of the installation process, and this without any manual action. We can do this in a very easy way via the installer (I will start again from the previous installer DLL we have created in this post).

Updating the installer

We will need to work at the end of the installation, ie on the "Commit" event. To do so :

  • Right-Click on the setup project and choose "View / Custom Actions"
  • Right-Click on the "Commit" event and choose "Add Custom Action"
  • Choose the "Primary Output from MyWindowsServiceInstallerActions" (from the Application Folder) and click OK

Now our installer DLL will also get called when the commit is occuring.

Starting the event

We can now update the installer class as follows :

using System.Collections;
using System.ComponentModel;
using System.Configuration.Install;
using System.IO;
using System.ServiceProcess;
 
namespace MyWindowsServiceInstallerActions
{
   [RunInstaller(true)]
   public partial class MyInstaller : Installer
   {
      //Other implementation remained unchanged, and so ommited here
 
      protected override void OnCommitted(IDictionary savedState)
      {
         base.OnCommitted(savedState);
 
         ServiceController service = new ServiceController("MyPersonalService");
         service.Start();
      }
   }
}

Some explanation about the code :

  • We could have decided to do the same treatment on the "Commit" event
  • The ServiceController class let's us manipulate a service (based on the service name, as set in the constructor of the service)
  • If for any reason, the "Start" method doesn't work (problem in the service, event log full, ...) an exception will get raised, and so the installation will fail and rollback.

A more secure implementation would be something like (you must of course include a reference to System.WindowsForms.dll if you want to use the MessageBox class) :

protected override void OnCommitted(IDictionary savedState)
{
   base.OnCommitted(savedState);
 
   ServiceController service = new ServiceController("MyPersonalService");
   string errorMessage = string.Format("Could not start the service {0}. You should launch it manually"
                                       service.DisplayName);
 
   //We'll try starting the service only if not started yet
   if ( service.Status == ServiceControllerStatus.Stopped )
   {
      try
      {
         service.Start();
         //Let's wait (for max 10 seconds) that this service is running
         service.WaitForStatus(ServiceControllerStatus.Running, new TimeSpan(0, 0, 10));
      }
      catch ( InvalidOperationException )
      {
         //The Start method failed
         MessageBox.Show(errorMessage);
      }
      catch ( System.ServiceProcess.TimeoutException )
      {
         //The Start method succeeded, but after 10 seconds, the service was still not running
         MessageBox.Show(errorMessage);
      }
   }
}
Note that we use the fully qualified name for the TimeOutException not to have any ambiguity with the same exception in the System namespace.

Billets liés

Ajouter un commentaire


 

  Country flag





Live preview

mars 12. 2010 15:36

Powered by BlogEngine.NET 1.2.0.0 | Theme by Pierre-Emmanuel Dautreppe