MSI Factory
A major upgrade is an installation where the product code changes. Typically this involves removing a previous installation and then installing a new version.
This differs from a minor upgrade or small update, because in both of those, the product code stays the same.
- Small update: a "quick fix" that only makes very small changes. The version number does not change. It's still the same product, so the product code stays the same.
- Minor upgrade: makes changes to the installed product. Can add and remove features, but cannot reorganize the feature-component tree. The version number is changed. It's still the same product, so the product code stays the same.
- Major upgrade: completely replaces the installed product. You can think of this as installing a separate product that is not compatible with the existing one, and requires that the existing one be removed first. Because it's a new, incompatible product, the product code is changed.
In general, a major upgrade is an installation that completely replaces a previous install. It might have the same name, and it might even be installed to the same place, but the product code is different. As far as Windows Installer is concerned, if the product code (GUID) is different, that makes it a completely different product.
Tip: Windows Installer sets the UPGRADINGPRODUCTCODE property when a major upgrade is being performed.
To create a major upgrade in MSI Factory:
- Set up the project as you would for a normal install.
- In Project Settings, use a new product code (unique to the new version).
- Add the programs that you want to replace to the "Find/remove related programs" list. Note that the related programs are referenced by their upgrade codes. Use the "Minimum version" and "Maximum version" fields to define the range of versions that will be removed.
Example - major upgrade from version 1.0.0 to 2.0.0:
- Set up the 2.0.0 project just like the 1.0.0 project.
- Go to the Project Settings/Product tab and generate a new Product Code.
- Add an item to the list of related programs, using the upgrade code from the 1.0.0 project. (Usually this will be the same upgrade code as in 2.0.0 as well.)
+ On the Related Program dialog, add a property to detect and remove the older version. Name it with a public name (all caps), e.g. OLDPRODUCTS. Set the minimum version to 1.0.0, inclusive. Set the maximum version to 2.0.0, not inclusive. Select the "Migrate features from upgraded products" option. Do not select the "Only detect (do not uninstall)" option, since you want the old versions to be removed.
+ If 1.0.0 and 2.0.0 have the same upgrade code: Add a second property to detect any future versions. You can use this property in conditions, for example to prevent this install from running if the user has already run an even newer one. Name it with a public name, e.g. NEWERPRODUCTFOUND. Set the minimum version to 2.0.0, not inclusive. Select the "Only detect (do not uninstall)" option.
A major upgrade requires that:
- the product code is different.
- the related programs that you want to remove have been defined.
- ALLUSERS is initially set to the same value that was used when the product was installed.
In order for a major upgrade to remove a previous version, the value of the ALLUSERS property at the beginning of the install must correspond to how that previous version was installed. If the initial ALLUSERS value does not match, the old version will not be removed.
Note that it's the value of ALLUSERS at the very beginning of the major upgrade setup that matters -- this isn't just a matter of choosing the same answer on the UserProfileDlg screen. By the time the setup has reached the user interface, it's already too late.
You will need to explicitly set the value of ALLUSERS for the major upgrade. Normally this can be done by setting the value directly in Project Settings, on the Properties tab. However, if you do not know what type of installation the user has selected, you will need to have them set the property on the command line, for example:
msiexec /i setup.msi ALLUSERS=1
...for a per-machine install, or
msiexec /i setup.msi ALLUSERS=""
...for a per-user install.
Note that the value you use depends on how the user chose to perform the original installation. Even if you didn't give the user the option to select per-machine or per-user on a dialog in the UI, they can still set the value of ALLUSERS on the command line.
Tip: If you're using the MSI Factory bootstrapper, you can use its MSI actions to programmatically determine what kind of installation was performed and set the appropriate ALLUSERS property on the command line.
If ALLUSERS does not match the type of installation that is being replaced, the old version will not be found by the FindRelatedPrograms action, and so it will not be removed. This means you will end up with two control panel entries -- one for the previous version, and one for the new one.
If the new version installs to a different location, then you will be able to uninstall each version separately.
However, if the new version installs to the same location, the results may seem a bit unexpected when the two versions are uninstalled. Specifically, when the new version (the major upgrade) is uninstalled, its control panel entry will be removed, but any files that replaced older versions will remain. So in the control panel it will look like the "old" version is installed, when some of the files are actually from the new version.
In both cases, in order to fully uninstall the product, you would need to uninstall both control panel entries.
If ALLUSERS was set correctly at the beginning of the major upgrade install, then the old version would be found and removed before the new version was installed. So the new version would effectively replace the old version's control panel entry, and there would only be one product to uninstall.
MSDN Online: Major Upgrades
MSDN Online: Preparing an Application for Future Major Upgrades
MSDN Online: RemoveExistingProducts Action
MSDN Online: FindRelatedProducts Action
MSDN Online: Using an Upgrade Code
MSDN Online: Changing the Product Code
MSDN Online: UpgradeCode Property
MSDN Online: ALLUSERS Property
MSDN Online: Upgrade Table
MSDN Online: UPGRADINGPRODUCTCODE Property
MSDN Online: Small Updates
MSDN Online: Minor Upgrades
Blog post: Where to place RemoveExistingProducts in a major MSI upgrade