Installing a Managed Service with a Custom Name (Part 3 of 4) [Robert Villahermosa]

What happened to specifying a custom name?

Ahh, I haven’t forgotten – this post was created to see how to let the user choose their own custom service name. Notice how I’ve hooked up two eventhandlers in my Project Installer code. BeforeInstall gets called at execution time prior to the service being installed and BeforeUninstall gets called prior to the service being uninstalled.

You can ask the user to specify the name of the service they’d like installed I the BeforeInstall event handler. Here, I’m just asking the user to enter the name of the service they’d like. When this gets installed using InstallUtil.exe, the install will wait for the user to enter a service name before continuing. There’s no magic involved – once InstallUtil.exe completes a service with the name of your choice appears in your service manager (run services.msc) to see it. You can also see that it gets registered in the registry under HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services.

At uninstall time, you need to know the name of the service that was installed in order to uninstall it. This brings me back to the initial problem that the customer had encountered – their service installed correctly, but failed to uninstall. What had happened? They failed to persist the service name in their install logic, so at uninstall time their installer was failing. Persisting the right data is one of the classic install/uninstall problems.

How do I persist the data?

In my example below, the service name gets peristed in install time into a text file called “Service.config”. Looking at the UninstallEventHandler, it just reads the name back out of this text file at uninstall time to remove the service. Of course, there are many ways you could persist the service name. I wrote it to a file for simplicity in this example but you could of course persist it somewhere else, such as in a registry key under your company name

Here’s the rest of the listing for the Installer:

 

private void BeforeInstallEventHandler(object sender, InstallEventArgs e)

{

// Add steps to perform any actions before the install process.

Console.WriteLine("BeforeInstallEventHandler Called");

Console.WriteLine("Enter the name you would like this service installed as:");

serviceInstaller.ServiceName = Console.ReadLine();

PersistServiceName(serviceInstaller.ServiceName);

Console.WriteLine("Attempting to install service as: " + serviceInstaller.ServiceName);

}

private void BeforeUninstallEventHandler(object sender, InstallEventArgs e)

{

Console.WriteLine("BeforeUninstallEventHandler Called");

serviceInstaller.ServiceName = RetrieveServiceName();

// Add steps to perform any actions before the Uninstall process.

Console.WriteLine("Code for BeforeUninstallEventHandler");

}

private void PersistServiceName(string serviceName)

{

//This method stores the service name,

you can choose whatever method to persist this data as you like

TextWriter tw = new StreamWriter("Service.config", false);

tw.WriteLine(serviceName);

tw.Close();

}

private string RetrieveServiceName()

{

string serviceName;

//This method retrieves the service name,

and should mirror the Perist method above

TextReader tr = new StreamReader("Service.config");

serviceName = tr.ReadLine();

tr.Close();

Console.WriteLine("ServiceName" + serviceName);

return serviceName;

}

}

 

<editorial notes>
Finally, tomorrow we'll see how Rob brings it all together!
</editorial notes>