1

I have web app, which I want to install on IIS. This app supports plugins architecture. It consists of:

  1. Core Part
  2. Plugin A
  3. Plugin B

I want to have 2 installers (msi). One for plugin A and other for plugin B. Each installer should also install Core Part. So if I run installer for plugin A it should install Core Part and Plugin A binaries. Then if I run Installer for plugin B it should install only Plugin B binaries. But if run installer for Plugin B as first it should install Core Part and Plugin B binaries.

I used WiX Merge Module project for Core Part and created 2 WiX projects for each installer. But it does not work as I want.

This is how it works:

  1. I run installer for Plugin A (works fine)
  2. I run installer for Plugin B, it detects that product is already installed, shows Remove, Repair, Change page
  3. I choose Change and I see "Plugin A" on features tree instead of "Plugin B"

You can see sample solution here: https://github.com/bwojdyla/wixplugins Works in Debug configuration. Wix 3.9, VS2012

My merge module (Core part):

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Module Id="CoreModule" Language="1033" Version="1.0.0.0">
        <Package Id="751e70eb-cf76-413b-b8c8-231a31f9c946" Manufacturer="test" InstallerVersion="200" />

    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="INSTALLFOLDER" Name="PluginInstaller">
        <Component Id="CoreComp" Guid="{161F78E1-0ABD-4FCD-92FC-6095A45F78B3}">
          <File Id="CoreFile" KeyPath="yes" Source=".\Core.txt" />
        </Component>
      </Directory>
    </Directory>
    </Module>
</Wix>

Plugin A:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="{8E93D1E7-C05F-40A0-B737-C053C1EE3E0A}" Name="PluginInstaller" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="eed33233-e773-45c2-87a1-ab349191a30a">
        <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Id="{9C7D28B4-FBAD-4FE6-A204-8F6A11D89792}"/>

        <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
        <Media Id="1" Cabinet="Cab1.cab" EmbedCab="yes" />

    <UIRef Id="WixUI_FeatureTree"/>

    <FeatureRef Id="ProductFeature">
      <Feature Id="PluginA" Title="Plugin A" Level="1" AllowAdvertise="no">
        <ComponentGroupRef Id="ProductComponents" />
      </Feature>
    </FeatureRef>
    </Product>

    <Fragment>
        <Directory Id="TARGETDIR" Name="SourceDir">
            <Directory Id="ProgramFilesFolder">
                <Directory Id="INSTALLFOLDER" Name="PluginInstaller" />
        <Merge Id="CoreModule" Language="1033" SourceFile="..\CoreModule\bin\Debug\CoreModule.msm" DiskId="1" />
            </Directory>
        </Directory>
    </Fragment>

    <Fragment>
        <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <Component Id="PluginAComp" Guid="{7641AF10-B2EF-4639-A0B4-34AE819CAD38}">
        <File Id="PluginAFile" KeyPath="yes" Source=".\PluginA.txt" />
      </Component>
        </ComponentGroup>
    </Fragment>
</Wix>

Plugin B:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
  <Product Id="{8E93D1E7-C05F-40A0-B737-C053C1EE3E0A}" Name="PluginInstaller" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="eed33233-e773-45c2-87a1-ab349191a30a">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" Id="{9C7D28B4-FBAD-4FE6-A204-8F6A11D89792}"/>

    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <Media Id="1" Cabinet="Cab1.cab" EmbedCab="yes" />

    <UIRef Id="WixUI_FeatureTree"/>

    <FeatureRef Id="ProductFeature">
      <Feature Id="PluginB" Title="Plugin B" Level="1" AllowAdvertise="no">
        <ComponentGroupRef Id="ProductComponents" />
      </Feature>
    </FeatureRef>

  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="INSTALLFOLDER" Name="PluginInstaller" />
        <Merge Id="CoreModule" Language="1033" SourceFile="..\CoreModule\bin\Debug\CoreModule.msm" DiskId="1" />
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
      <Component Id="PluginBComp" Guid="{D11704D9-9911-483A-B204-B2171DCB0E67}">
        <File Id="PluginBFile" KeyPath="yes" Source=".\PluginB.txt" />
      </Component>
    </ComponentGroup>
  </Fragment>
</Wix>

Or maybe there is other wix feature, which I should use, to achieve this?

bwojdyla
  • 85
  • 10

2 Answers2

0

Windows Installer identifies and reference counts components by their GUID; so basically what you need to do is to make sure that the common part components ("core") is included in both products with the same component guids. I.e. in principle you could achieve this not necessarily by creating a merge module, but for example by #including the code for the "core" part into both modules. Anyways, merge module is fine - it basically does more or less the same thing.

What is important, you should have different product ids and package ids for the PluginA and PluginB, otherwise they look the same to the Windows Installer (it identifies the product being installed by it's guid). Now when you try to install B it thinks that it's actually A being uninstalled, thus you get this message.

So you could try to change your product A/B files like this (note that I have omitted also the "packageid" - it is auto-generated, and basically all MSIs should have different package ids).

Product A

  <Product Id="{4D7828A0-F55C-4D26-9AA9-914FF646C55E}" Name="PluginInstallerA" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="eed33233-e773-45c2-87a1-ab349191a30a">
      <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

Product B

<Product Id="{E052B5C0-BB4D-4848-844C-2293059E9465}" Name="PluginInstallerB" Language="1033" Version="1.0.0.0" Manufacturer="test" UpgradeCode="eed33233-e773-45c2-87a1-ab349191a30a">
  <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

Here the reference counting is it explained in details: MSI Reference Counting: Two products install the same MSIs

Community
  • 1
  • 1
Nikolay
  • 10,752
  • 2
  • 23
  • 51
0

In these situations both packages always install the core part. That's the normal situation. You don't want to be in the situation where you install A and the core and then install B without the core because uninstalling A will then remove the core that B is using. The core is in both so the ref counting means that you can install both and then uninstall one and the core will still be there. All that happens when B is installed over A is either nothing (because the file versions are the same and they're in the same locations) or some files are updated (because the plugin installed last has updated versions of the files in the common location). As Nikolay says, you arrange for all this to work by having a single core part (as in a merge module added to both MSIs) or by otherwise ensuring that the sharing based on component guids is correct.

PhilDW
  • 20,260
  • 1
  • 18
  • 28