WIX: When upgrading, what to do when there are 2 different UpgradeCodes? - wix

After getting a good answer here: WIX: How can I uninstall a previous MSI built using a VS *.vdproj, now i'm facing a different issue in the field.
I have 2 versions out there, with 2 different UpgradeCodes. That happened because we already deployed one version of the new WIX w/out syncing the UpgradeCode with the old MSI.
Syncing the new Wix installer with one of the codes, upgrade goes smoothly. Am I hosed on the second one? I tried to just uninstall the extra one from Add/Remove and that worked smoothly, but before I instruct those users to go to Add/Remove, I wanted to know if there's another trick to handle both.
Maybe if I can somehow detect during installation which version is installed, can i set the new Wix UpgradeCode dynamically?

Put both UpgradeCodes into the Upgrade table into two separate rows. This allows you to have the MSI automatically uninstall the older MSIs during an upgrade (if that's what you want), as well as give you MSI properties to use conditionally to check what's already installed on the system.
Update (to respond to the first comment)
<!-- old product -->
<Upgrade Id="$(var.UpgradeCode1)">
<UpgradeVersion Property="OLD_PRODUCT_FOUND_1"
IncludeMaximum="yes"
Maximum="2.0.0"
MigrateFeatures="yes"
OnlyDetect="no" />
</Upgrade>
<!-- new product -->
<Upgrade Id="$(var.UpgradeCode2)">
<UpgradeVersion Property="OLD_PRODUCT_FOUND_2"
IncludeMaximum="yes"
Maximum="3.0.0"
MigrateFeatures="yes"
OnlyDetect="no" />
</Upgrade>
This code will detect both UpgradeCodes, and if one (or both) are found will remove them during the RemoveExistingProducts action.

To detect the older version I would look into using a custom action.

Related

WiX Installer: how to remove old Product versions?

Developer created 3 installers of the same product and changed the UpgradeCode (yes, I know, but it is).
These installers were provided to customers and some of them used these versions.
Now I have built the new installer, then added records to the msi using SuperOrca: to uninstall the old product installations with incorrect upgrade codes.
How I can do it in WiX installer project do not using SuperOrca to patch the msi every time after it is built?
Upgrade code should not change. In an installer if you are releasing another major version you can change the product code but the Upgrade code should be same of a product throughout the lifetime. Add below tags inside product tag in Wix to automatically uninstall the previous version when you install the new version-
<Product Id="*" UpgradeCode="PUT-GUID-HERE" ... >
<Upgrade Id="PUT-GUID-HERE">
<UpgradeVersion OnlyDetect="no" Property="PREVIOUSFOUND"
Minimum="1.0.0.0" IncludeMinimum="yes"
Maximum="99.0.0.0" IncludeMaximum="no" />
</Upgrade>
<InstallExecuteSequence>
<RemoveExistingProducts After="InstallInitialize" />
</InstallExecuteSequence>
As OnlyDetect is set to No the wix will automatically uninstall the previous version after the InstallInitialize phase. Wix will detect the version from the range that you have mentioned as example given above-Minimum-1.0 to maximum-99.0
Many people seem to be under the impression that an upgrade can only upgrade one install and that there's something wrong with changing upgrade codes, but none of this is required. The Upgrade table in an MSI file can upgrade as many installed products as you like, as you know from using SuperOrca.
So all you need to do is add Upgrade elements naming the UpgradeCode values and range of versions you need. If there are three products that might be installed then add the three Upgrade elements naming them all. You'll end up with an Upgrade table (look in the MSI) that will turn out the same as if you added them with Orca.

How to disable downgrade and enable upgrade in wix installer?

I want to remove the older version and install the latest version setup. If installing the older version means, need to restrict the downgrade.
I have enabled the upgrade and removed the older version if exist using below code.
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="{Guid}">
<UpgradeVersion Minimum="1.1.0.1" Maximum="99.0.0.0"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
<RemoveExistingProducts Before="InstallInitialize" />
But i don't know how to disable the downgrade option. I am getting solution to restrict the downgrade for 3 digit(x.x.x) version. But can get solution to restrict 4 digit(x.x.x.x) version.
There is no support in Windows Installer (and therefore in WiX generation of MSI major upgrades) for major upgrade logic based on four fields of the ProductVersion. As the docs say:
https://msdn.microsoft.com/en-us/library/windows/desktop/aa370859(v=vs.85).aspx
"Note that Windows Installer uses only the first three fields of the product version. If you include a fourth field in your product version, the installer ignores the fourth field."
The issue is that a major upgrade requires a change in the first 3 fields, so using four fields means you can't use a major upgrade of any kind. You might be able to create a custom bootstrapper that looks at installed versions and incoming upgrade versions, and it would detect attempts to downgrade, but you'd need to uninstall that older version then install the upgrade separately, and there would be recovery, no single transaction to restore the system in case of failure somewhere. The rules say three fields are used in major upgrades.

How do you uninstall another program in wix installer?

I have lost the GUID's for my old installer. I managed to get the upgrade id using Orca but it still does not remove the old version from the programs and features list. How can I uninstall an old msi/bootstrapper with a completely new one?
If you have a MSI to uninstall (i.e. not a bootstrapper) then you should be able to uninstall it with WIX <Upgrade> element, by specifying it there like that:
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is installed." />
<Upgrade Id="{YOUR-OTHER-STUFF-GUID-HERE}">
<UpgradeVersion OnlyDetect="no" Property="OTHER_STUFF_FOUND" Minimum="0.0.0" />
</Upgrade>
If you have some EXE to uninstall, not MSI, then AFAIK only a custom action is a solution (just execute the uninstall line using custom action).
-Make use of the windows installer API: MsiEnumRelatedProducts() to get a list of all the products that share the same UpgradeCode.
https://msdn.microsoft.com/en-us/library/aa370103(v=vs.85).aspx
This API returns the product code of all the products installed on the system that share the same UpgradeCode.
You can probably see examples of the usage of this over the internet or Windows installer SDK.
Also, there was one related question recently:
WiX - Allowing a *manual* uninstall of one msi to uninstall another msi that shares the same UpgradeCode (and not just during the MajorUpgrade)
-The other approach is to upgrade your old msi package using the new msi package.
http://wixtoolset.org/documentation/manual/v3/howtos/updates/major_upgrade.html
Another way would be reading Uninstall key (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall) from registry and look for your application name / publisher and if match found execute the UninstallString command.

How to retain the previous version of app on user cancel - Wix Installer Upgrade

eI have an APP Installer using Wix.
Now I need to Upgrade the APP without uninstallation of the previous version. So I have been using the following method for upgrading my APP, Without uninstallation.
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="7c4d0532-0ee4-49e8-92f4-77792293fcab">
<UpgradeVersion
Minimum="1.0.0.0" Maximum="99.0.0.0"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
And during installation of new version, it uninstalls the app and installs the new version.
But when user cancels the wizard immediatly after the unisntallation of the earlier version, The entire app is lost from the PC.
The new version installation gets cancelled and the prvious version gets uninstalled.
The Roll back operation is not happened and the previous version is not retaind.
Is there any method to Retain the previous version in this scenario.
Assuming there's no other problem, the RemoveExistingProducts action must be between InstallInitialize and InstallFinalize for the transaction to roll back and reinstall the old product. You didn't say where your REP is sequenced.
If it IS between those two actions then the issue may be that the reinstall of the original product is failing. It's just been uninstalled and is now being reinstalled as a rollback of its uninstall, and that scenario may not be one the product can deal with. Check the verbose log.

Wix - replacing seperate 32bit and 64-bit MSIs with one newer 32-bit MSI

Background
We have a 64 and 32 bit version of an MSI:
app.msi
app_x86.msi
these have been created with Wix and have separate upgradeCodes defined for each MSI.
We also have a WIX bundle EXE that decides on which MSI to use according to platform.
The Problem
The 64-bit version no longer exists, we want ALL upgrading clients (MSI or EXE, 32 ot 64-bit) to use the 32-bit version.
I guess I need 2 MSIs still, each with matching the old upgrade codes, 1 for 32-bit and 1 for 64-bit but will identical content....
Ideally I'd have 1 MSI have can upgrade 2 different upgradeCodes but I guess that's not possible.
I hope the above is clear.... we've tried :
- produce a single 32-bit dll (app_x86.msi)
- copy to matche the previous 64 bit (app.msi)
- ensure both MSIs have the same upgrade code as before
And yet we end up with a side-by-side install.
Adding another answer since I need code formatting. This Wix sample seems like a pretty good basic start.
I don't have this machine set up properly for testing this XML code, but something like this should work:
Upgrade table entry for X32:
<Property Id="PREVIOUSVERSION_X32" Secure="yes" />
<Upgrade Id="YOUR_GUID_X32_EDITION">
<UpgradeVersion
Minimum="1.0.0" Maximum="99.0.0" Property="PREVIOUSVERSION_X32"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
Upgrade table entry for X64:
<Property Id="PREVIOUSVERSION_X64" Secure="yes" />
<Upgrade Id="YOUR_GUID_X64_EDITION">
<UpgradeVersion
Minimum="1.0.0" Maximum="99.0.0" Property="PREVIOUSVERSION_X64"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
Here is a snapshot of how a similar upgrade scenario might be implemented in the compiled MSI file:
You can add several upgrade codes to the upgrade table and uninstall them as part of your install. See this sample too.
An upgrade code identifies a "family of products" (or technically a number of product codes that match the upgrade code) and each entry in the upgrade table will define a common upgrade strategy for all of the product codes that match that particular upgrade code.
In other words you can just add the two different upgrade codes to your upgrade table, author the remaining fields and this should work. You probably need two ActionProperties. Remember to add them both to the SecureCustomProperties. I believe Wix takes care of this automagically. If this isn't done the PUBLIC property values are not passed from the client to the server installation process on secure client PCs (which is most PC's with newer Windows versions) and X-files problems result. The client process runs with interactive user rights, and the server process runs with LocalSystem (full system access).