Jan Schreuder on .Net

.Net code samples, experiences, observations

View my professional profile on LinkedIn

Recent Posts

Tags

News

  • Inappropriate comments will be deleted at my discretion.

    The information and code samples in this weblog is provided "AS IS" without warranty of any kind, either expressed or implied, including but not limited to the merchantability and/or fitness for a particular purpose.

Community

Email Notifications

Tool suppliers

Tools

General

Microsoft

Favorite blogs

Archives

How to: Code Service Dependencies

On my current assignment we develop and maintain a number of Windows services. Some of these service depend on others. The problem we faced when we needed to deploy new versions, is that services did not start in the correct order. Some services depend on others, so these need to be started first.

This is documented in the release notes we send to the system administrators, but we were still faced with problems caused by this. We finally solved the problem by coding the service dependencies into the ServiceInstaller class for each service project. That way, the system will know if a service can be started or not.

So here's how it works.

Finding the correct ServiceName

When you want to code a dependency to a service, you will first need to know the ServiceName by which the service is know to the system. This information is stored in the registry. It is perfectly legal to use the DisplayName to identify the service your service depends on. But the DisplayNames can change between cultures. A Spanish DisplayName is very likely to be different from a German or English DisplayName. The ServiceName is fixed, so the better choice to define dependencies.

When you look at the Services window in Administrative Tools, you will always see the DisplayName of a service, but never the ServiceName. But this is where the .Net Framework comes in.

First create a new project for a Console Application. Then add a reference to System.ServiceProcess.DLL. When you're done, open the class that contains the static void Main() method and replace the entire code in that class file with the code below.

using System;
using System.ServiceProcess;
 
namespace ServiceInfo2
{
    /// <summary>
    /// Summary description for Class1.
    /// </summary>
    class Class1
    {
        private static void WriteLine(string service, string display)
        {
            Console.WriteLine(string.Format("{0} - {1}", service.PadRight(32, ' '),  display));
        }
 
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            ServiceController [] sc = ServiceController.GetServices();
 
            WriteLine("ServiceName", "Display name");
 
            for (int i = 0; i < sc.Length; i++)
            {
                WriteLine(sc[i].ServiceName, sc[i].DisplayName);
            }
            Console.ReadLine();
        }
    }
}

When you run this, the application will list the ServiceName and DisplayName for all services installed on the system.

Add the dependencies to the InstallerClass

Now that you have the full list of services and their corresponding ServiceName and DisplayName values, it is very easy to find the ServiceName for the service that your service depends on. When you have found that name, all that is left is to add the correct information to the InstallerClass in your Windows Service Project.

If, for example, the service depends on the COM+ System Application running, then all you need to do is specify COMSysApp as a dependency for your service. This can be done in the constructor of your InstallerClass. Below is a small example. The line that is important here is the one that contains the property ServicesDependedOn. 

using (ServiceProcessInstaller processInstaller = new ServiceProcessInstaller())
{
    processInstaller.Account = ServiceAccount.LocalSystem;
    processInstaller.Username = null;
    processInstaller.Password = null;
 
    using (ServiceInstaller installer = new ServiceInstaller())
    {
        installer.DisplayName = "My wonderful windows service.";
        installer.StartType = ServiceStartMode.Automatic;
        installer.ServiceName = "MyService";
 
        installer.ServicesDependedOn = new string [] { "COMSysApp" };
 
        this.Installers.Add(processInstaller);
        this.Installers.Add(installer);
    }
}

By assigning the ServiceName(s) of the service(s) that your service depends on here, will make sure that the dependencies are registered in the system registry at installation time.

Beware

You will have to be very careful when you use this solution. It is very easy to create circular dependencies this way. You're services might never start this way.

Comments

Salim Jendoubi said:

Thanks, it was helpfull :)

# November 5, 2008 10:38 AM

Benjamin Howarth said:

This is really useful! I'm debugging two services at the moment (one is dependent on the other but isn't configured as such) so this is much appreciated.

# November 14, 2008 12:07 PM

Matthieu said:

Thanks a lot!!!!!!!!!!!!!!!!

# November 19, 2008 10:41 AM
Leave a Comment

(required) 

(required) 

(optional)

(required)