We are in the process of upgrading our installer from a Visual Studio Installer project (*.vdproj) to a WiX installer. From our users point of view we would like to make this transition as seamless as possible. I.e. if they have version 1.0 of our software that was installed using an MSI from the *.vdproj build, then the v2.0 install using the MSI from the WiX build should overwrite/remove the old version and continue as normal.
The problem we have encountered is that the original *.vdproj installer installed the software as "ALLUSERS=false" whereas now with WiX we would like to use InstallScope="perMachine" (i.e. "ALLUSERS=true").
We are using a bootstrapped WiX installer where the first element in the chain handles the .Net Framework installation (if necessary) and the second element is the MSI installer for our product.
This is what our first attempted upgrade code looks like [1][2]:
<MajorUpgrade DowngradeErrorMessage="A newer version of ... is already installed." />
<Upgrade Id="{UPGRADE-CODE-OF-OLD-INSTALLER}">
<UpgradeVersion OnlyDetect="no" Property="OTHER_STUFF_FOUND" Minimum="0.0.0" />
</Upgrade>
If we set InstallScope="perUser" in our new WiX installer, then this will work as desired however if we set InstallScope="perMachine" then the uninstall fails with this error logged:
MSI (c) (04:10) [23:18:49:626]: FindRelatedProducts: current install is per-machine. Related install for product '{PRODUCT-CODE-OF-OLD-INSTALLER}' is per-user. Skipping...
After some research we have learned that this is a known issue and that a solution as straightforward as what is written above is not possible because Microsoft installers prevent context switching (i.e. from perUser to perMachine).
The question is: how can we handle this upgrade in a robust manner? At the moment we have no working solution.
I can think of a few options, but wanted to see if people had better answers, suggestions on which option was best, or suggestions on how to implement one of these listed approaches:
- use a custom action to manually uninstall the old software OR provide a warning to the user to manually uninstall the old version and terminate the installation. If we know the Upgrade Code of our old installer, we should be able to search the registry to see if the old software is installed? When I have looked in the re
- can I have a second WiX MSI installer that runs as InstallScope="perUser" and is solely responsible for removing the old installation?
- I have found this solution [3], however because we are using a Bootstrapped installer, the tags in our MSI project are not executed so it doesn't work for us.
- change our new WiX installer to "perUser" and deal with this problem some time in the future (not the ideal solution)
Regarding uninstalling an old perUser install. It seems there can be issues with this if a different user is logged in compared to the one that was initially used for the per user installation? Are there any issues here that we should be aware of?
UPDATE
I have tried the approach using a CustomAction in which I call MsiEnumRelatedProducts
using the Upgrade Code to see if the previous version of our software is installed, and then calling
msiexec /X {PRODUCT-CODE-FOUND-USING-MsiEnumRelatedProducts} \q
to uninstall the old version. However, this does not work as it seems MSI uses a Mutex lock to ensure only one MSI operation can be carried out at a time..