Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VB

Using Single EXE to Deploy Multiple Windows Service

4.00/5 (11 votes)
2 Sep 2007Public Domain1 min read 1   713  
To set the Windows Service name in a Setup project instead of in Project Installer of the WIndows Service project

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():
VB.NET
Private Sub InitializeComponent()
' (other initialization code)
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.

VB.NET
' Force Setup project to specify the service name in CustomActionData
' in "Install" Custom Install Action Developer should set the same name
' in CustomActionData in "Uninstall" Custom Install Action
Private Sub DoBeforeInstall(ByVal Sender As Object,
    ByVal Args As System.Configuration.Install.InstallEventArgs)
    Handles MyBase.BeforeInstall
    ' Context when Install
    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

' Developer should set the same name in CustomActionData in "Uninstall"
' Custom Install Action
Private Sub DoBeforeUninstall(ByVal Sender As Object,
    ByVal Args As System.Configuration.Install.InstallEventArgs)
    Handles MyBase.BeforeUninstall
    ' Context when Uninstall
    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
        'WriteLog("Me.ServiceInstaller1 Is Nothing")
    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:

Screenshot - CustomerAction.jpg

Run the setup, a Windows Service called DynamicService is installed.

Screenshot - Servicesmsc.jpg

Points of Interest

  1. For setup of multiple services on the same machine, each setup should have a different [ProductCode] and [UpgradeCode].
  2. You may also change the Windows Service description using this technique.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication