0
votes

I've been trying to write a Wix installer which is capable of installing multiple instances of a Windows Service side by side. I am using WIX v3.5 (can't upgrade due to other issues).

The following Product.wxs works to install either the default instance or Instance1. When attempting to install one of the instances when the other is already installed, the installer runs and exists without giving any errors but nothing is installed.

Does anybody have any advice?

Thank you!

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <?if $(var.Platform) = x64 ?>
    <?define ProductId = "FC66F94F-A3B8-4435-8F7F-B9A19D773871" ?>
    <?define ProductName = "MCSS FTP Notification Worker (64 bit)" ?>
    <?define Win64 = "yes" ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
    <?define PlatformPath = "x64"?>
  <?elseif $(var.Platform) = ia64 ?>
    <?define ProductId = "4068DAB4-8480-41BA-B0BB-7CBE4B5C2320" ?>
    <?define ProductName = "MCSS FTP Notification Worker (64 bit)" ?>
    <?define Win64 = "yes" ?>
    <?define PlatformProgramFilesFolder = "ProgramFiles64Folder" ?>
    <?define PlatformPath = "ia64"?>
  <?else ?>
    <?define ProductId = "38F55942-579B-4617-9352-4A8FBEF3E491" ?>
    <?define ProductName = "MCSS FTP Notification Worker" ?>
    <?define Win64 = "no" ?>
    <?define PlatformProgramFilesFolder = "ProgramFilesFolder" ?>
    <?define PlatformPath = "x86"?>
  <?endif ?>

  <Product Id="$(var.ProductId)" 
       Name="$(var.ProductName)" 
       Language="1033" 
       Version="!(bind.FileVersion.NotificationWorkerExe)" 
       Manufacturer="Company" 
       UpgradeCode="54982507-16ae-4f38-b887-605576b58c09">
    <Package InstallerVersion="200"
         Compressed="yes" 
         Manufacturer="Company"
         Description="$(var.ProductName)"
         Keywords="SSO,MasterCustomer,NotificationWorker,MSI"
         Comments="(c) 2013 Company"
         Platform="$(var.PlatformPath)"/>

    <Condition Message='.NET Framework 4.0 must be installed prior to installation of this product.'>
  MsiNetAssemblySupport >= "4"
    </Condition>

    <Property Id="INSTANCENAME" Value="Instance0" />

    <Property Id="ARPCOMMENTS" Value="Company" />
    <Property Id="ARPCONTACT" Value="Contact" />

    <!-- No repair or modify in Add/Remove Programs-->
    <Property Id="ARPNOMODIFY" Value="0" />
    <Property Id="ARPNOREPAIR" Value="0" />

    <InstanceTransforms Property="INSTANCENAME">
      <Instance Id="Instance1" ProductCode="773476D9-6A5D-49DA-9762-3FDF3822E9B6" ProductName="Inst1 Worker"/>
    </InstanceTransforms>

<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

    <Directory Id="TARGETDIR" Name="SourceDir">
  <Directory Id="$(var.PlatformProgramFilesFolder)">
        <Directory Id="BaseDir" Name="Base">
          <Directory Id="INSTALLLOCATION">
            <Component Id="CreateEventSource64BitFullNet4" Guid="82A6A90A-E889-4C9A-ADF2-07C539198800" Win64="$(var.Win64)">
              <CreateFolder/>
              <!-- Create an Event Source -->
              <Util:EventSource
                    xmlns:Util="http://schemas.microsoft.com/wix/UtilExtension"
                    Name="MasterCustomer"
                    Log="LogName"
                EventMessageFile="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\EventLogMessages.dll" />
            </Component>
            <Component Id="RemoveFiles" Guid="BFF360CF-3625-49C8-98E3-DE9632489A80" Win64="$(var.Win64)">
              <RemoveFile Id="PurgeFolder" Name="*.*" On="uninstall" />
            </Component>
            <!-- Registry keys -->
            <Component Id="RegistryEntries" Guid="*">
              <RegistryKey Root="HKLM"
                       Key="Software\Company\MC\[INSTANCENAME]NotificationWorker"
                       Action="createAndRemoveOnUninstall">
                <RegistryValue Type="string" Name="Version" Value="!(bind.FileVersion.NotificationWorkerExe)"/>
                <RegistryValue Type="string" Name="InstallLocation" Value="[INSTALLLOCATION]"/>
              </RegistryKey>
            </Component>

            <!-- Assemblies -->
            <Component Id="NLog" Guid="HJHFAA3B-4F47-46DD-9DF3-B2A61E888E87" Win64="$(var.Win64)">
              <File Id="NLog" Name="NLog.dll" Vital="yes" Source="..\packages\NLog.2.0.1.2\lib\net40\NLog.dll"/>
              <CreateFolder />
            </Component>

            <Component Id="Microsoft.Practices.TransientFaultHandling.Core" Guid="C5A67C33-B1BB-481B-9C1E-8F47676CB41E"
                   Win64="$(var.Win64)">
              <File Id="Microsoft.Practices.TransientFaultHandling.Core" Name="Microsoft.Practices.TransientFaultHandling.Core.dll"
                Vital="yes" Source="..\packages\TransientFaultHandling.Core.5.1.1209.1\lib\NET4\Microsoft.Practices.TransientFaultHandling.Core.dll"/>
              <CreateFolder />
            </Component>
            <Component Id="EntityFramework" Guid="3CD35D63-16AE-432A-BA6D-B769804B680B"
                   Win64="$(var.Win64)">
              <File Id="EntityFramework" Name="EntityFramework.dll"
                Vital="yes" Source="..\packages\EntityFramework.5.0.0\lib\net40\EntityFramework.dll"/>
              <CreateFolder />
            </Component>

            <Component Id="EntityFramework.Extended" Guid="C656CF9D-FCD3-495A-B08F-5D5BBBBA52DA"
                   Win64="$(var.Win64)">
              <File Id="EntityFrameworkExtended" Name="EntityFramework.Extended.dll"
                Vital="yes" Source="..\packages\EntityFramework.Extended.5.0.0.71\lib\net40\EntityFramework.Extended.dll"/>
              <CreateFolder />
            </Component>

            <Component Id="Ninject" Guid="93D6ACFB-45BF-4DAF-87B3-D10B450123BE"
                   Win64="$(var.Win64)">
              <File Id="Ninject" Name="Ninject.dll"
                Vital="yes" Source="..\packages\Ninject.3.0.1.10\lib\net40\Ninject.dll"/>
              <CreateFolder />
            </Component>

            <Component Id="Ploeh.AutoFixture" Guid="605611B1-349A-4E58-A321-22F059E27CB2" 
                   Win64="$(var.Win64)">
              <File Id="Ploeh.AutoFixture" Name="Ploeh.AutoFixture.dll"
                Vital="yes" Source="..\packages\AutoFixture.2.16.2\lib\net35\Ploeh.AutoFixture.dll"/>
            </Component>

            <Component Id="Newtonsoft.Json" Guid="8D699222-D357-49B2-BCED-BD070E06E3C1"
                   Win64="$(var.Win64)">
              <File Id="NewtonsoftJson" Name="Newtonsoft.Json.dll" Vital="yes"
                Source="..\packages\Newtonsoft.Json.4.5.11\lib\net40\Newtonsoft.Json.dll"/>
            </Component>

            <Component Id="Logger"
                   Guid="F0CC2705-1AE5-4092-8648-3B32F3ADD7D6"
                   Win64="$(var.Win64)">
              <File Id="LoggerDll"
                Name="Logger.dll"
                Source="$(var.Logger.TargetDir)Logger.dll"
                KeyPath="yes" />
              <CreateFolder />
            </Component>

            <Component Id="Services.Common"
                   Guid="E2507B7D-6160-43C1-6C49-158943C75938"
                   Win64="$(var.Win64)">
              <File Id="ServicesCommonDll"
                Name="Services.Common.dll"
                Source="$(var.Services.Common.TargetDir)Services.Common.dll"
                KeyPath="yes" />
            </Component>

            <!-- For the actual service -->
            <Component Id="NotificationWorkerComponent" Guid="13E74C65-429A-490E-974D-5D3D656EB3E8" Win64="$(var.Win64)">
              <File Id="NotificationWorkerExe"
                Name="Customer.Change.NotificationWorker.exe"
                KeyPath="yes"
                Source="$(var.Customer.Change.NotificationWorker.TargetDir)Customer.Change.NotificationWorker.exe"/>
              <ServiceInstall Id="NotificationWorkerService"
                          Name="Customer.Change.[INSTANCENAME].NotificationWorker.exe"
                          DisplayName="MCSS [INSTANCENAME] Notification Worker"
                          Type="ownProcess"
                          Start="auto"
                          ErrorControl="normal"
                          Description="Notifies external systems of customer changes"
                          Vital="yes">
                <ServiceConfig DelayedAutoStart="yes" OnInstall="yes" />
              </ServiceInstall>
              <CreateFolder />
              <ServiceControl Id="StartMCSSNotificationWorker"
                          Remove="uninstall"
                          Stop="both"
                          Name="Customer.Change.[INSTANCENAME].NotificationWorker.exe"
                          Start="install"/>
            </Component>
            <Component Id="NotificationWorkerConfigComponent"
                   Guid="43474C5A-AB13-49B4-8C21-7266F74C0F44"
                   Win64="$(var.Win64)">

              <File Id="NotificationWorkerConfig"
                Name="Customer.Change.NotificationWorker.exe.config"
                Source="$(var.Customer.Change.NotificationWorker.TargetDir)Customer.Change.NotificationWorker.exe.config"
                KeyPath="yes" />
              <Util:XmlFile Id="DebugOff"
                        xmlns:Util="http://schemas.microsoft.com/wix/UtilExtension"
                        ElementPath="//configuration/appSettings/add[\[]@key='Debug'[\]]/@value"
                        Action="setValue"
                        Value="false"
                        File="[#NotificationWorkerConfig]"/>
              <Util:XmlFile Id="SetSystem"
                        xmlns:Util="http://schemas.microsoft.com/wix/UtilExtension"
                        ElementPath="//configuration/appSettings/add[\[]@key='SystemToNotify'[\]]/@value"
                        Action="setValue"
                        Value="[INSTANCENAME]"
                        File="[#NotificationWorkerConfig]"/>
            </Component>
          </Directory>
        </Directory>
  </Directory>
</Directory>

    <Feature Id="ProductFeature" Title="MasterCustomer" Level="1">
        <!-- TODO: Remove the comments around this ComponentRef element and the Component above in order to add resources to this installer. -->
        <!-- <ComponentRef Id="ProductComponent" /> -->

        <!-- Note: The following ComponentGroupRef is required to pull in generated authoring from project references. -->
  <Feature Id="NotificationWorkerFeature"
           Title="MCSS Notification Worker"
           Description="Installs the MCSS Notification Worker Service"
           Level="1">
    <ComponentRef Id="CreateEventSource64BitFullNet4"/>
    <ComponentRef Id="RegistryEntries"/>
    <ComponentRef Id="NLog"/>
    <ComponentRef Id="Microsoft.Practices.TransientFaultHandling.Core"/>
    <ComponentRef Id="EntityFramework"/>
    <ComponentRef Id="EntityFramework.Extended"/>
    <ComponentRef Id="Ninject"/>
    <ComponentRef Id="Newtonsoft.Json"/>
    <ComponentRef Id="Logger"/>
    <ComponentRef Id="Services.Common"/>
    <ComponentRef Id="NotificationWorkerComponent"/>
    <ComponentRef Id="NotificationWorkerConfigComponent"/>
    <ComponentRef Id="RemoveFiles"/>
  </Feature>
  <ComponentGroupRef Id="Product.Generated" />
    </Feature>
</Product>
</Wix>
1

1 Answers

0
votes

MSI does not install your NotificationWorkerComponent because it is already installed. The decision whether to override the old version (you could not possible expect it to have same file side by side, only one version of the same component may persist), is made based on file information. In your case, it is the same component with the same GUID, and probably the same file, so nothing is installed.

I suggest using different components for each version of each file you want to have side by side.