Mailbag: How can I revert shared files to older versions when uninstalling the new version of my MSI-based product?

Question:

I have 2 versions of my MSI, and each version installs some files to a shared location.  After installing version 1 of my MSI, then version 2 of my MSI, the shared files are updated to version 2.  When I uninstall version 2 of my MSI afterwards, the shared files are still version 2.  However, I need the shared files to be reverted back to version 1.  How can I implement that behavior in my MSI?

Answer:

Windows Installer does not have any built-in functionality to back up old versions of shared files and them restore them when uninstalling the upgraded files.  The general philosophy that is being applied here is that if a shared file is upgraded, new versions of any shared files are expected to be backwards compatible with older versions of the product that depend on those files.

If backwards compatibility is not possible for your products and you need to restore older versions of shared files when uninstalling the newer version of your MSI, you will have to write custom actions to copy older versions of the files to a backup location during installation of the new version of the MSI and to restore the older versions of the files during uninstallation of the new version of the MSI.

The custom actions should behave as follows:

  • The custom action that backs up older versions of the files needs to be sequenced before the InstallFiles standard action and should have an execution condition that includes (NOT Installed) so it will run during a first-time install of the MSI and not during repairs or uninstalls.
  • The custom action that backs up older versions of the files needs to handle the case where the shared files do not exist.  In this case, it should skip trying to back up the older versions of the files so that install will not fail if the user does not have an older version of your MSI installed.
  • The custom action that restores older versions of the files needs to be sequenced after the RemoveFiles standard action and have an execution condition that includes REMOVE=”ALL” so it will only run during an uninstall of the MSI.
  • The custom action that restores older versions of the files needs to handle the case where the backup location does not exist.  In this case, it should skip trying to restore the older versions of the files so that uninstall will not fail if the user only has one version of your MSI installed.

Note – this solution also assumes that your MSIs follow the Windows Installer component rules – you cannot change composition of MSI components that are shared by multiple products.  In other words, shared files must be authored in MSI components that have the same GUID and same contents (files + install locations) in both versions of your MSI.