Install .NET Windows Service with a Different Name
Creating a Windows service in .NET could hardly be any easier. There's a template in Visual Studio which sets everything up and there's even a detailed walkthrough published on MSDN which leads you through the whole process from creating a new project to actually installing the service.
Installing multiple instances of such a service on a single computer is not that easy. You could do it by using Sc.exe
instead of InstallUtil.exe
, or you could modify the installer in your Windows service project to support configurable names. I prefer the latter approach, but there's not much documentation about it, which is probably the reason for many articles on the web describing over-complicated custom solutions instead of taking advantage of the APIs that are already available.
InstallUtil.exe
has built-in support for passing the arguments to Windows service's Installer
class. The Installer
base class parses them and puts them in a handy StringDictionary
, which can be accessed through InstallContext
. This means, you can read these values inside your Installer
and use them to change the default service name:
private void SetServiceName()
{
if (Context.Parameters.ContainsKey("ServiceName"))
{
serviceInstaller1.ServiceName = Context.Parameters["ServiceName"];
}
if (Context.Parameters.ContainsKey("DisplayName"))
{
serviceInstaller1.DisplayName = Context.Parameters["DisplayName"];
}
}
Of course, it's important, where this code is called from. If you try putting it in the class constructor, the installer will fail, because Context
is not yet initialized. Fortunately the base class provides many virtual methods which you can override to get access to the Context
after initialization. In our case we need to override OnBeforeInstall
and OnBeforeUninstall
:
protected override void OnBeforeInstall(IDictionary savedState)
{
SetServiceName();
base.OnBeforeInstall(savedState);
}
protected override void OnBeforeUninstall(IDictionary savedState)
{
SetServiceName();
base.OnBeforeUninstall(savedState);
}
The desired service name can now be passed as an argument to InstallUtil.exe
:
installutil /ServiceName=A.Service /DisplayName="A Service" .\WindowsService1.exe
The same goes for uninstall:
installutil /u /ServiceName=A.Service .\WindowsService1.exe
To use the default name, the parameters can simply be omitted.