Introduction
My project required me to package one Windows Service EXE with different configuration files for different customers. This article will demostrate how to modify ProjectInstaller to support this requirement.
Background
My company has a Windows Service product. When deployed to different customers, we want to give only a simple Setup.exe (with *.msi) to the customers for easy deployment. We want to use a different name for the Windows Service being installed.
For example, for customer ABC, after setup, the name of the Windows Service would be "ABC Service".
We will package different configuration / data files using the same EXE.
Using the Code
In standard Windows Service Project Installer, the Service Name is set in
Sub InitializeComponent()
:
Private Sub InitializeComponent()
Me.ServiceInstaller1.ServiceName = "Service1"
End Sub
The problem is that the ServiceName
is hardcoded in the service.exe. Setup project will invoke the Project Installer in the service.exe and use Service1
as the Windows Service name. We want to choose the name in the Setup project instead.
Hence, we add some code to handle BeforeInstall
and BeforeUninstall
events.
Private Sub DoBeforeInstall(ByVal Sender As Object,
ByVal Args As System.Configuration.Install.InstallEventArgs)
Handles MyBase.BeforeInstall
If GetContextParameter("SERVICENAME") = "" Then
Throw New Exception("SERVICENAME undefined")
End If
If Not Me.ServiceInstaller1 Is Nothing Then
Me.ServiceInstaller1.DisplayName = GetContextParameter(
"SERVICENAME")
Me.ServiceInstaller1.ServiceName = GetContextParameter(
"SERVICENAME")
End If
End Sub
Private Sub DoBeforeUninstall(ByVal Sender As Object,
ByVal Args As System.Configuration.Install.InstallEventArgs)
Handles MyBase.BeforeUninstall
If GetContextParameter("SERVICENAME") = "" Then
Throw New Exception("SERVICENAME undefined")
End If
Me.ServiceInstaller1.DisplayName = GetContextParameter("SERVICENAME")
Me.ServiceInstaller1.ServiceName = GetContextParameter("SERVICENAME")
End Sub
Public Function GetContextParameter(ByVal key As String) As String
Dim sValue As String = ""
If Me.Context Is Nothing Then
End If
Try
sValue = Me.Context.Parameters(key).ToString()
Return sValue
Catch
sValue = ""
Return sValue
End Try
End Function
In Setup project property, specify the [ProductName]
. It will be used as the Windows Service Name (e.g. DynamicService
).
In Custom Action, specify the same SERVICENAME
for custom action Install and Uninstall:
Run the setup, a Windows Service called DynamicService
is installed.
Points of Interest
- For setup of multiple services on the same machine, each setup should have a different
[ProductCode]
and [UpgradeCode]
. - You may also change the Windows Service description using this technique.