3

We have a problem that a fie is not installed upon a major update

  • We have a major update with <MajorUpgrade Schedule="afterInstallInitialize"...
  • We an old component with 1 file (xyz.exe Version 12.34) from a external manufacturer
  • We have now a new file from a new manufacturer and with the same name (xyz.exe Version 2.34). The new file has a lower version number than the old one.
  • We created a new component in the install package and removed the old component (in fact we gave it a new guid)
  • Changing the name of the exe isn't possible, it would have to much influence upon documentation and internal functions.

On a normal installation everything is OK.

But what happens now on an update:

  • The installer starts.
  • And detects that the new component exists (xyz.exe) with a lower version, so it will not be installed.
  • the installer runs and removes the old component
  • But it doesn't install the new because it just detected that the component was already installed.
  • Doing a repair installation fixes the problem and the file is than again present.

Setting the KeyPath to the Component fixes the problem. But it seams wrong to me. The directory where this file is installed is the main installation directory.

How to force the installation of this component?

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
xMRi
  • 14,982
  • 3
  • 26
  • 59
  • There are a number of ways to approach this: **`1)`** companion file, **`2)`** fake version information in the msi, **`3)`** hack-update version number in file using visual studio, **`4)`** setting a custom reinstallmode, **`5)`** move the file and create a new component with new guid, **`6)`** rename file and create new component guid, etc... 5 and 6 de-couples the new file from the sins of the past - but with a new downgraded file the problem could re-surface. [Here is a previous answer](https://stackoverflow.com/a/54766353/129130). – Stein Åsmul Mar 25 '20 at 00:25
  • Hacking a version number with Visual Studio (open binary as a resource and then set a new version number and save file) is kind of crazy, but it actually works to "remove the problem" in most cases (all cases that I have seen). It can cause new problems though - such as major confusion as to what version you are dealing with from the vendor - obviously. Maybe you can change only one of the versions (product versus file version - never tried - not sure which is needed for MSI, I would think file version). Procedure can be found in link above, bottom of answer. – Stein Åsmul Mar 25 '20 at 00:29
  • Hacking the version number in the file isn't possible. It would break the signature. And this signature is required. Faking the version in the MSI will require to do this fore now and the future... What is a custom reinstallmode? – xMRi Mar 25 '20 at 07:50
  • I will write it up below I think. REINSTALLMODE is unwanted to use because it applies globally to the whole setup and can cause a number of side-effects. I will try to link to the descriptions. I will first just commit an answer with the command line to use. – Stein Åsmul Mar 25 '20 at 17:49
  • 1
    I would recommend you try the companion file approach instead of REINSTALLMODE. – Stein Åsmul Mar 25 '20 at 18:10

1 Answers1

3

Similar Answer: How to Explicitly Remove dll During Majorupgrade Using Wix Toolset


Major Upgrade Downgrade: In order to overwrite binaries with higher version numbers on major upgrades there are a couple of preferred options:

  • The preferred approach would be to use a companion file (third party files).
  • Or if you can: compile a new binary with a higher version number (for your own files).

Companion Files: A snippet below on how to use companion files in WiX:

<..>

<Component Id="MyFile.exe" Feature="Main">
  <File Id="MyFile.exe" Source="MyFile.exe"></File>
</Component>

<!-- Do not re-use any GUIDs in your own sources! (very important) -->
<Component Id="MyFile_2.exe" Guid="{00000000-0000-0000-0000-3D82EA2A99AF}" Feature="Main">
  <File Source="MyFile_2.exe" CompanionFile="MyFile.exe"></File>
</Component>

<..>

One-Line Summary: In the second component we point to the first component's file so that MyFile_2.exe will install whenever MyFile.exe is installed - regardless of versioning issues.


Then there are a number of further options:


REINSTALLMODE: The MSI property REINSTALLMODE can be used - but it has a number of side-effects:

Setup 1: Version 1.0.0 for a setup:

msiexec.exe /i Setup1.msi /qn

Setup 2: Version 2.0.0 for the major upgrade setup:

msiexec.exe /i Setup2.msi REINSTALLMODE=amus /qn

Several Problems: There are several issues with REINSTALLMODE that makes it an unsafe feature to use (try emus instead? See documentation - a little less brute force maybe). It is a shame that this setting applies to all features in the setup - that makes it very dangerous:

  • can downgrade shared files system-wide - if there are merge modules included - for example (features in Windows are in place to prevent most of this problem: WFP and WRP in Vista an beyond - non-Microsoft merge modules can still cause problems for non-Microsoft shared files)
  • can cause inconsistent version estate since an old package can be installed after a newer one and downgrade only some of the shared files
  • can downgrade or wipe-out settings in non-versioned files and registry settings (note to self: test this again, there are complexities with component settings)
  • can cause a significant increase in the number of requested reboots due to attempts to needlessly replace in-use files of the same version (the real fix for this is to shut down services properly and to use the restart manager to allow applications to be shut down automatically during deployment - on file locks).
  • there are several further issues that are quite specific

Hack Binary Version: An ugly, but effective option is to change the version of the actual binary file using Visual Studio to set a higher version number (you open the binary as a resource and set a new version - this is obviously very different from compiling a new version of the binary using visual studio source code compilation). There are several side effects:

  • you break digital signatures
  • you can create "version confusion"
  • there are risks involved writing a new binary from Visual Studio
  • it is a "hack manual step" - you might need to keep doing this for new versions?
  • etc...

Move, Rename: If you can de-couple the new file from the old by renaming it or moving it you can work around the problem. If you get a new version again for the future, you might have to do this again. Clunky.

"Load From": Putting the file somewhere shared and load it from that specific location and removing the old copy from your installation folder. Could that work? This means the file could also be delivered by another setup at that location.


Version Lying: In Installshield there is a concept of being able to set a specific version number to a file. I am not sure how to implement that in WiX. There is also an "always overwrite option" that apparently sets a maximum value for the version so the existing file is always overwritten.


Some Links:

Stein Åsmul
  • 39,960
  • 25
  • 91
  • 164
  • So when your installer package is self contained (meaning no shared files etc), then REINSTALLMODE="amus" is a safe choice? I don't understand all the drawbacks mentioned "amus", e.g: "can downgrade or wipe-out settings in non-versioned files and registry se.....". What does this mean? "amus" and "omus" overwrite non-versioned files, so it would not make a difference for non-shared files) – Dan Jan 26 '22 at 21:22
  • We tried REINSTALLMODE=amus for our selfcontained installers (no shared files). They worked well when executed normally (user clicking on msi) but we encountered problems when they run in a powershell (triggered by C# code) so we had to rollback to omus. We are clueless why exactly this happened but for us amus is no option. I wonder why amus even exists when its unstable. – Dan Feb 17 '22 at 09:58