0
votes

After some googling I came up with a configuration that should allow me to install only newer versions of my package (which it does) while replacing the older, already installed version(s) (which it doesn't)

My wxs file is as follows:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
    <Product Id="*"
             Name="Gdml File Viewer" Language="1033"
             UpgradeCode="5fb07c15-32a5-4b8a-9794-e4425bfc2eea"
             ...>
        <Package InstallerVersion="200"
                 Compressed="yes"
                 InstallScope="perMachine" Platform="x64" />
        <MajorUpgrade Schedule="afterInstallValidate"
                      DowngradeErrorMessage="A later version of [ProductName] is already installed"
                 AllowSameVersionUpgrades="no"
                 AllowDowngrades="no" />
...

As expected it does allow me to install newer versions, but the older version is not uninstalled. It still shows up in the "Apps & features" list:

Apps & features

(The other instance has version 2019.14.181.35181)

1

1 Answers

2
votes

Logging: To properly debug a failed major upgrade you need to create a proper log file (various ways to create log file - also by policy).

msiexec.exe /i C:\Path\Your.msi /L*v C:\Your.log

Auto-logging could be on: check the TEMP folder for any auto-generated log files there. If not, run again on a virtual to reproduce the upgrade problem with logging enabled.


Failed Major Upgrade: When you see two entries in Add / Remove Programs your major upgrade has failed (generally). You need to fix the configuration of the Upgrade table. See likely causes listed below.

Minimal WiX Markup: The minimal WiX markup for a default upgrade table - with normal parameters (which works fine, see below with screenshot) - is just:

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

Advanced: It is even possible to combine the above "convenience element" for simple major upgrade configuration with old-style elements for total control of Upgrade table content. Samples here.


On Major Upgrades: MajorUpgrade and Upgrade elements. How to use them:


Likely Causes: A short summary of some of many possible causes for failed major upgrades.

  • Mismatched Upgrade Code: There might be a mismatch in the upgrade codes between the old and the new version of the MSI so the products are not identified as related. This should leave two versions installed afterwards (uninstall of old version never happened).

  • Missing Upgrade Code: Just adding that it is possible for the upgrade code to be missing from the Product element. This is generally an error, unless you want to do something specifically weird.

  • Missing MajorUpgrade Element: The whole Major Upgrade element can be missing and no Upgrade element present. The latter is for manual configuration of major upgrades, the former for "auto-magical" implementation of typical major upgrade scenarios. Sort of "best practice".

  • ProductVersion: There might not have been a bump up of one or more of the first 3 digits in the product version (fourth field ignored).

  • Product Code: As a side-note you might get a warning that the product is already installed, this means the product code has NOT changed (which it should for a major upgrade).

  • Dangling Version: It is also possible that your WiX markup is fine, and you have a dangling older version that was never correctly configured, if so uninstall it manually and try again or try on a clean virtual. If you auto-generate the product GUID you can end up with several versions of your product installed at once if the major upgrade isn't set up properly.

  • Installation Context: MSI files can install per-user or per-machine. If you have an installation per-user and then run a per-machine installation it will not detect the previous version. Do you have any hard coded references to ALLUSERS in your package?

  • SecureCustomProperties: Quickly - while I remember - in secure environments (corporate environments with users running without admin rights) you need to add the ACTION property from the Upgrade table to the list of secure properties (properties allowed to be passed to deferred mode).

  • Package Code: A very special case I have seen is when the new package has the same package code as the old one (or an existing installed package). This is an extreme design error and must not occur. Always auto-generate the package code, it is the right way to do things. Windows Installer will treat the two packages as identical by definition (as opposed to actual fact - you won't believe the X-Files that can result).

Further Details: Some further things to remember:

  • A major upgrade is essentially an uninstall of the older version and an installation of the new version with a number of scheduling options for the order in which actions take place (install new first, then uninstall old or vice versa).

  • As stated above you could also have a straggling older version of a setup on the box that wasn't properly configured or some X-Files nonsense happened that causes it to fail upgrade. Happens.

  • Unlikely with WiX, but it is possible for the standard action RemoveExistingProducts to be missing from the InstallExecuteSequence.

WiX Learning Curve: Suggest using some samples to help speed up the learning process. The only thing that really helps? Here are some WiX Quick Start Suggestions. There are sample links in there.

Minimal WiX Sample: There is this old sample: Transparent Aluminum. Essentially a walk-through of how to use Votive to create a WiX-based installer. It includes a major upgrade element. I believe this simple configuration adds the protection against downgrade that you seek:

<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />

See the Upgrade table that results:

Orca

Test Case: Using the Transparent Aluminum as test project, you can try this procedure to make the upgrade work:

  1. Set the product code to * in order to auto-generate a new ProductCode for every build ("<Product Id="*" ...").
  2. Compile the first version of your MSI. Right click WiX project in solution view in Visual Studio and select Open Folder in File Explorer. Into bin and Debug or Release.
  3. Rename the compiled MSI by adding _1 to the end of the file name. For example: MySetup_1.msi
  4. Now bump up one of the first 3 digits of the product version field in the WiX source: <Product Id="*" ... Version="2.0.0"
  5. Compile a new MSI and rename it: MySetup_2.msi
  6. Install the MSI files starting with version 1 and then the second one. Verify that major upgrade succeeded.

Advanced: Here is a demo of an advanced way to configure major upgrades using a combination of the convenience element "MajorUpgrade" and the older "Upgrade" elements (that allow you more fine-grained control of the resulting Upgrade table):

Adding entries to MSI UpgradeTable to remove related products

And here is a sample of using only the older Upgrade elements resulting in more work, but total control of the Upgrade table: Major Upgrade - "The Old, Manual Way".


Links: