1
votes

I'm building my first WiX installer after becoming sick of the sight of Wise For Windows Installer!

I've built the installer and that works fine, but now I need to get it to perform an upgrade from the previous version of my app. While I can find plenty of post about setting up WiX do perform upgrades, I can't find anything telling me how to do it when you have a previous installer made using another tool.

Do I do it the same way? Do I need to get upgrade codes, etc, from the old installer? Many thanks in advance!

UPDATE:

Following fletcher's instructions I got the UpgradeCode from the old installer using dark.exe and added it to the Product tag's UpgradeCode. The start of my WiX file now looks thus...

<Product Id="fcdc6617-e960-46db-8faa-1dc627f250c8" Name="MyProduct"
       Language="1033" Version="1.2.0.5165" Manufacturer="MyCompany" 
       UpgradeCode="{E97A233B-AB49-4B66-B92A-68972F6D72B9}">

    <Package InstallerVersion="200" Compressed="yes" />

<!-- Upgrade from previous version(s) -->
<Property Id="PREVIOUSVERSIONINSTALLED" Secure="yes" />
<Upgrade Id="{E97A233B-AB49-4B66-B92A-68972F6D72B9}">
  <UpgradeVersion Minimum="1.1.0.4605" Maximum="1.2.0.5165"
                  Property="PREVIOUSVERSIONINSTALLED"
                  IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>

...but now when I run this installer I end up with two instances of MyProduct on the target machine. Where am I going wrong?

4

4 Answers

4
votes

In WiX v3.5 there is also the new MajorUpgrade element that makes all this authoring much easier.

2
votes

It sounds like you want to do a Windows Installer Major Upgrade. Adding the Upgrade table will find the existing product and set your PREVIOUSVERSIONINSTALLED property to the product code.

To remove the old product during your install you need to add the RemoveExistingProducts action to your Execute sequence. There are some choices you have to make on where to sequence this in. The most basic way is to uninstall the old application early in the execute sequence by adding:

<RemoveExistingProducts Before="InstallInitialize" /> 

You can do the remove later in the execute sequence but you have to be more careful of component rules.

1
votes

Finally found a solution this morning, thanks everyone who pointed me in the right direction (including DAVID GARDINER's blog). Making sure the Upgrade code is the same as the previous installer, and that both the Product code has changed and the version number has been incremented, here is the full solution:

<Product Id="fcdc6617-e960-46db-8faa-1dc627f250c8" Name="$(var.ProductName)"
       Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)" 
       UpgradeCode="$(var.UpgradeCode)">

<Package InstallerVersion="200" Compressed="yes" />
<Media Id="1" Cabinet="media1.cab" EmbedCab="yes" />

<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<!-- without this next line the upgrade doesn't work! (not sure why?) -->
<Property Id="ALLUSERS" Value="1" /> 

<Upgrade Id="$(var.UpgradeCode)">

  <UpgradeVersion Property='PREVIOUSVERSIONSINSTALLED' 
                  OnlyDetect="no" IncludeMinimum='yes' 
                  Minimum='1.1.0.4605' IncludeMaximum='no' 
                  Maximum='$(var.Version)' />

  <UpgradeVersion Minimum="$(var.Version)" 
                  IncludeMinimum="no" OnlyDetect="yes" 
                  Language="1033" 
                  Property="NEWERPRODUCTFOUND" />

</Upgrade>

...

<InstallUISequence>

  <Custom Action="UIandAdvertised" Sequence="3">
    ProductState=1
  </Custom>

  <LaunchConditions After="AppSearch" />
</InstallUISequence>

<CustomAction Id="PreventDowngrading" Error="Newer version of this product is already    installed." />
<CustomAction Id="UIandAdvertised" Error="Something about the UI."/>

<!-- Remove exist products before install -->
<InstallExecuteSequence>

  <Custom Action="PreventDowngrading" After="FindRelatedProducts">
    NEWERPRODUCTFOUND AND NOT Installed
  </Custom>

  <LaunchConditions After="AppSearch" />
  <RemoveExistingProducts Before="InstallInitialize" />
</InstallExecuteSequence>
</Product>
1
votes

I had a similar problem and finally figured it out by running my installer with verbose logging.

The existing installation of my application was getting ignored because it was installed with InstallScope="per-machine" while the default is per-user.

"FindRelatedProducts: current install is per-user.  Related install for product '{GUID}' is per-machine.  Skipping..."

To solve, I added InstallScope to my package element:

<Package Id='*' ... InstallScope="perMachine"/>

I hope this helps!