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

December 2006 - Posts

IE7 remembers login information?!?!?!

I have IE7 installed on the machine I use to develop at my current assignment. I noticed something strange this morning and I'm not sure if I should be happy, or extremely worried.

I was reading my company email using the Outlook web client and I accidentally closed the tab that contained the Outlook web client. I opened a new tab and was presented with the standard opening page. I clicked the button to logon and expected to see the logon dialog. Instead, I got my inbox. IE7 had logged me back into the web mail client without bothering to check my credentials.

Now on one hand, it saved me time. On the other hand, if I just close the tab and not IE7, anyone with access to the system can logon to my inbox. I know of course, that you should always lock your system before you walk away from your desk. It's just something you tend to forget, or just not worry about. I will have to remember to be more cautious with IE7 tabs.

Posted: Dec 11 2006, 09:43 AM by Jan Schreuder | with 2 comment(s)
Filed under:
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.