Blog
What are Upgrades?

MSI Upgrades From a Windows Installer perspective, upgrade packages are fully functional packages that can install software applications on a clean machine. Package developers might require previous versions before installations can proceed, but this requirement is simply a licensing control—the package itself contains all the information necessary to install the package on a clean workstation. An upgrade package includes additional information that helps it identify upgrade candidate packages on the target workstation. Its internal structure is also designed by the package developer to coordinate with previous versions of the package. There are three key attributes of a Windows Installer package that are used to designate what type of update a package is. These attributes are:
- Package code—the package code is a GUID that is stored in the summary information stream. A package code indicates that two Windows Installer packages will perform identically when executed. Only functionally identical packages should share the same package code. Package codes function similarly to hash codes, which ensure that two file versions match exactly (like CRCs). Windows Installer cannot use hashes to determine identical functionality because MSI files contain a database that might vary in physical organization between two identical copies of a file and Windows Installer packages can be functionally identical but structured differently. For instance, an MSI file with compressed source files and an administrative install share from that package have very different physical file structures but perform identically when installed.
- Product code—Product code is a GUID stored in the property table. Just like a component code is the authoritative identification of a component a product code is the authoritative identification of a software product. Two packages should only have the same package code if they are the same major release of the software package. Two instances of the same identical packages should always have the same product code. Sloppy or uncoordinated repackaging processes can cause identical repackaged applications to have multiple package codes deployed to production computers. This can result in upgrade packages not recognizing upgrade candidate packages installed on computers to which they are deployed.
- Product version—Product version is a period delimited numeric value stored in a property that usually coincides with the version number of the software application. The format is w.x.y.z where w is major version, x is minor version, y is the build number, and z is a further revision number. If product versions are not properly managed, upgrade packages might fail to apply to upgrade candidate packages on computers to which they are deployed.
How does an Upgrade work?
A standard Windows Installer package will perform upgrades steps as follows:
- Identify upgrade candidates (installed packages that can be upgraded by the currently installing package).
- Install new and updated components.
- Remove unneeded components.
The last two steps in this sequence might seem backward. This sequence is meant to address the issue of ever-growing software applications. Take Microsoft Office for instance. Say that a given configuration of Microsoft Office takes 950MB on disk. Further, imagine that an update to Microsoft Office requires 10MB of new and updated files and the deletion of 4MB of files. If a full de-install and reinstall is performed, then 950MB of files are deleted and 960MB of files are copied. Windows Installer’s method of installing new and updated components and then deleting unneeded components reduces this load to 10MB of file copies and 4MB of deletions.
Types of Upgrades
The type of update can be characterized by the changes the update makes to the application’s product code, product version, and package code. The application’s product version is stored in the ProductVersion property. The application’s product code is stored in the ProductCode property. The application’s package code is stored in the Revision Number Summary Property. When deciding whether to change the product version, you should consider if future versions of the application will need to differentiate between the updated and non updated versions of the current product. To ensure differentiation in the future, a minor upgrade should be used instead of a small update.
- If an update changes the .MSI file and application files, but does not change the ProductCode property or ProductVersion property, it is termed a small update.
- If the update changes the ProductVersion, but does not change the ProductCode, it is termed a minor upgrade.
- If the update changes the installation into an entirely different product, the ProductCode must change and the update is termed a major upgrade.
Different types of Upgrades
Type of update | Product Code | Product Version | Description |
Small Update | No change | No change | An update to one or two files that is too small to warrant changing the ProductVersion. The package code in the Revision Number Summary Property does change. Can be shipped as a full installation package or as a patch package. |
Minor Upgrade | No change | Changed | A small update making changes significant enough to warrant changing the ProductVersion property. Can be shipped as a full installation package or as a patch package. |
Major Upgrades | Changed | Changed | A comprehensive update of the product warranting a change in the ProductCode property. Shipped as a patch package or as a full product installation package. |
What are small Updates?
A small update makes changes to one or more application files that are too minor to warrant changing the product code. A small update is also commonly referred to as a quick fix engineering (QFE) update. A small update does not permit reorganization of the feature-component tree.
How are small updates applied by Reinstalling the Product?
A small update can be applied to an application by completely or partially reinstalling the application from the command line or from a program. To propagate the small update to current users (this is a complete reinstall) from the command line
- From the command line use either: msiexec /fvomus [path to updated .MSI file] or msiexec /I [path to updated .MSI file] REINSTALL=ALL REINSTALLMODE=vomus.
- The updated .MSI file is cached on the user’s computer. To propagate a small update to current users (this is a complete reinstall) from a program
The following method launches a reinstallation of only those features or components that are affected by the small update. To propagate a small update to current users (this is a partial reinstall)
- Obtain a list of the names of features and components that are affected by the small update.
- From the command prompt use: msiexec /I [path to updated .MSI file] REINSTALL= [Feature list] REINSTALLMODE=vomus
- The updated .MSI file is cached on the user’s computer.
What are Minor Upgrades?
A minor upgrade is an update that makes changes to many resources. None of the changes can require changing the ProductCode. A minor upgrade can be used to add new features and components but cannot reorganize the feature-component tree. A typical minor upgrade includes all fixes in previous small updates combined into a patch. A minor upgrade is also commonly referred to as a service pack (SP) update. A minor upgrade changes the ProductVersion property. A minor upgrade and a small update differ in that a minor upgrade changes the package code and product version. Minor upgrades are shipped as a full product installation package or as a patch package. However, a minor upgrade cannot use a different volume label for the new version.
What are Major Upgrades?
A major upgrade is a comprehensive update of a product that needs a change of the ProductCode Property. A typical major upgrade removes a previous version of an application and installs a new version. A major upgrade can reorganize the feature component tree. To fully enable the installer upgrade capabilities, each package should have an UpgradeCode Property and an Upgrade Table. Each stand-alone product or product suite should have its own UpgradeCode. Each record in the Upgrade table gives a combination of the upgrade code, product version, and language information used to identify a set of products affected by the upgrade. When the FindRelatedProducts Action detects that an affected product is installed on the system, it appends the product code to a property in the ActionProperty column of the Upgrade table. The RemoveExistingProducts action and the MigrateFeatureStates Action remove or migrate the products listed in the ActionProperty list. A major upgrade can be shipped as a Patch Package or as a full product installation package. You can condition custom actions that are sequenced after InstallValidate to handle major upgrades by using the UPGRADINGPRODUCTCODE property:
- If you want a custom action to run during an uninstallation of the product, but not during the removal of the product by a major upgrade, use this condition.
REMOVE=”ALL” AND NOT UPGRADINGPRODUCTCODE
- If you want a custom action to run only during a major upgrade, use the. UPGRADINGPRODUCTCODE condition
When not to change the Product Code?
The product code is a GUID that is the principal identification of an application or product. An update that meets the following guidelines generally does not require a change of the product code and can be handled as a small update, or if the version is to change, as a minor upgrade:
- The update can enlarge or reduce the feature-component tree but it must not reorganize the existing hierarchy of features and components. It can add a new feature to the existing feature-component tree. If it removes a parent feature, it must also remove all the child features of the removed feature.
- With Windows Installer prior to version 2.0, the update can add a new component only if that component is associated with a new feature. Beginning with Windows Installer version 2.0, a new component can be added to an existing feature.
- The update must not change the component code of any component. Consequently, a small update or minor upgrade must never change the name of a component’s key file because this would require changing the component code.
- The update must not change the name of the .MSI file of the installation package. Instead, because it modifies the package, it should change the package code. Note that this means that the update can change the tables, custom actions, and dialogs in the .MSI file without changing the file’s name.
- The update can add, remove, or modify the files, registry keys, or shortcuts of components that are not shared by two or more features.
- The update of a component that is shared by two or more features must be backward compatible with all applications and features that use the component. The update can modify the resource of a shared component, such as files, registry entries, and shortcuts, as long as the changes are backward compatible. It is not recommended that the update add or remove files, registry entries, or shortcuts from a shared component.
When to change the Product Code?
The product code must be changed if any of the following are true for the update:
- Coexisting installations of both original and updated products on the same system must be possible.
- The name of the .MSI file has been changed.
- The component code of an existing component has changed.
- A component is removed from an existing feature.
- An existing feature has been made into a child of an existing feature.
- An existing child feature has been removed from its parent feature.
- When using a version of the installer prior to version 2.0, the product code must be changed if a component has been added to an existing feature. With version 2.0, and later versions, a component may be added to an existing feature without requiring a product code change.
Note that adding a new child feature, consisting entirely of new components, to an existing feature does not require changing the product code. To install new features with minor upgrades, using a version of the Windows Installer earlier than version 2.0, you must list the new features on the command line as values of the ADDLOCAL property. You must explicitly set the REINSTALL property to the list of features to be reinstalled and not simply set REINSTALL to “ALL”. Beginning with version 2.0, minor upgrades are no longer required to install new child features by using the ADDLOCAL property. Instead, new child features can be authored by including msidbFeatureAttributesFollowParent and msidbFeatureAttributesUIDisallowAbsent in the Attributes field of the Feature table. If the minor upgrade only adds new child features, then REINSTALL=ALL is sufficient to force the installation of the new child features.
How to prepare an Application for Future Major Upgrades?
Every application, or suite of applications, should be assigned an UpgradeCode Property, ProductVersion Property, and ProductLanguage Property. The UpgradeCode property indicates a family of related applications consisting of different versions and different language versions of the same product.
The following steps should be followed while preparing an application for future major upgrades
- Determine a new package code value for the application. Enter the new package code into the Revision Number Summary Property of the Summary Information Stream.
- Determine a new ProductCode property for the application.
- Determine the application’s version and the ProductVersion property. The ProductVersion should increase with each new version of the application. Note that the 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.
- Determine the language of the package and the ProductLanguage property. The value of this property must be a numeric language identifier (LANGID). Enter ProductLanguage and its value into the Property table. Note that the FindRelatedProducts action uses the language returned by MsiGetProductInfo. For FindRelatedProducts to work correctly, the package author must be sure that the ProductLanguage property is set in the Property table to a language that is also listed in the Template Summary property.
- If you are authoring an installation package for the first version of your product, use a new UpgradeCode. If your package is intended for a newer version of an existing product, or is the same version as an existing product in a different language, use the same UpgradeCode as the existing product. No two products with the same ProductVersion and the same ProductLanguage can have the same UpgradeCode, unless one is a small update of the other.
- The UpgradeCode has the format of a GUID. Enter the UpgradeCode GUID into the Property table.
How to prevent an Old Package from Installing Over a Newer Version?
Windows Installer upgrade packages can be authored to have major upgrades not install if a user already has a newer version installed. The procedure in this topic can only prevent downgrades that might be caused by running a major upgrade package. This procedure relies on the FindRelatedProducts Action, which only runs during a first-time installation and does not run in maintenance mode (reinstallation). Because minor upgrades are performed using reinstallation, this procedure cannot be used to determine whether a minor upgrade package is attempting to downgrade an application.
To prevent an old package from installing over a newer version
- Enter the UpgradeCode Property for the group of related products that may be eligible to receive this upgrade into the UpgradeCode column of the Upgrade Table.
- Enter the msidbUpgradeAttributesOnlyDetect bit flag in the Attributes column of the Upgrade Table.
- Enter the version of the upgrade provided by this package into the VersionMin column of the Upgrade Table. Leave the VersionMax column blank.
- Enter the name of the property that is to be set by the FindRelatedProducts Action into the ActionProperty column of the Upgrade Table.
- Add the SecureCustomProperties property and the property named in the ActionProperty column of the Upgrade Table to the Property Table.
- Add a Custom Action Type 19 after the FindRelatedProducts action in the InstallExecuteSequence Table. Include a record in the CustomAction Table for this action and enter the text to be displayed in the Target column. The type 19 custom action is built into the installer, so there is no code to write.
- Enter the name of the ActionProperty into the Condition column of the record in InstallExecuteSequence Table that contains the Custom Action Type 19. This conditions the custom action to only be executed when the Upgrade Table detects that a newer version is already installed.
Why should UpgradeCode be used?
The UpgradeCode is primarily used for supporting major upgrades, although small and minor upgrade patches may use the UpgradeCode for product validation. During major upgrades, the FindRelatedProducts, MigrateFeatureStates, and RemoveExistingProducts actions detect, migrate, and remove previous versions of the product. The FindRelatedProducts action searches for products using criteria based upon the UpgradeCode, ProductLanguage, and ProductVersion. These criteria are specified in the Upgrade table. Given the criteria used by the FindRelatedProducts action, the UpgradeCode can be the same for different languages and versions of a single product. This is because the Upgrade table allows for differentiating between products along version and language lines. Across different versions of the same product, you may never need to change the UpgradeCode. Each stand-alone product should have its own UpgradeCode. A product suite should also have its own UpgradeCode. Doing so will allow the suite to upgrade previous versions of the suite or stand-alone products by using multiple rows in the Upgrade table.
The following two scenarios illustrate the use of the UpgradeCode.
- Product A and Product B were shipped with the same ProductLanguage, ProductVersion, and UpgradeCode. Product A and Product B have different ProductCodes. Because the products were assigned the same UpgradeCode, the Upgrade table cannot be authored to differentiate the older version of Product A from the older version of Product B. In this case, you will be unable to have an upgrade installation of Product A that ignores Product B. Because these were different products, they should have each been assigned a different UpgradeCode.
- The English and French versions of Product A were shipped with the same ProductVersion and UpgradeCode. Both the English and French versions of Product A have different ProductLanguages and ProductCodes. Even though both the English and French language versions share the same UpgradeCode, it is possible to author the Upgrade table such that only the older English language version will be detected and upgraded and the older French version ignored. Different language versions of a product can use the same UpgradeCode.
How to apply Major Upgrades by Installing the Product?
A major upgrade can be applied by installing the new installation package for the upgraded product. Because major upgrades get a different product code than the original product, installing the upgrade must be treated as an installation of a new product. The upgrade can simply be installed like another product. You can have the new installation package handle the removal of the old product by including the Upgrade table and the FindRelatedProducts action and RemoveExistingProducts action. To propagate a major upgrade to current users from the command line, use: msiexec /i [path to updated MSI file]
Where to place RemoveExistingProducts Custom Action?
The RemoveExistingProducts action must be scheduled in the action sequence between one of the following locations.
Between the InstallValidate action and the InstallInitialize action. In this case, the installer removes the old applications entirely before installing the new applications. This is an inefficient placement for the action because all reused files have to be recopied.
After the InstallInitialize action and before any actions that generate execution script.
Between the InstallExecute action, or the InstallExecuteAgain action, and the InstallFinalize action. Generally the last three actions are scheduled right after one another: InstallExecute, RemoveExistingProducts, and InstallFinalize. In this case the updated files are installed first and then the old files are removed. However, if the removal of the old application fails, then the installer rolls back both the removal of the old application and the install of the new application. After the InstallFinalize action. This is the most efficient placement for the action. In this case, the installer updates files before removing the old applications. Only the files being updated get installed during the installation. If the removal of the old application fails, then the installer only rolls back the uninstallation of the old application