Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio
All postings are provided AS IS with no warranties, and confer no rights. Additionally, views expressed herein are my own and not those of my employer, Microsoft.
When I create an MSI-based installer, one of the things I typically include in the setup authoring is some logic to allow me to implement Windows Installer major upgrades if/when I need to release a new version of the MSI in the future. I typically include this authoring even if I don't currently plan to release a future version that I would need to use it for. Doing so gives me flexibility if/when I decide to update the MSI in the future.
There are some specific things you need to include in your MSI to enable major upgrades, and as I've learned about how to do this, I've found that the information is scattered around in several different places (MSDN, WiX documentation, blog posts, etc). As a result, I decided to create a couple of simple samples that I copy and paste from each time I create new MSI-based installers using WiX v3.0.
This blog post will use the samples that I created and posted at http://cid-27e6a35d1a492af7.skydrive.live.com/self.aspx/Blog%7C_Tools/WiX%20Samples/wix%7C_sample%7C_major%7C_upgrade.zip to demonstrate how to implement Windows Installer major upgrade functionality in an MSI created with WiX v3.0.
Step 1: Add upgrade information needed to cause new versions to upgrade older versions
In order to allow major upgrades, an MSI must include the following information:
Note - Windows Installer looks for other installed MSIs with the same UpgradeCode value during the FindRelatedProducts action. If you don't specifically schedule the FindRelatedProducts action in your setup authoring, WiX will automatically schedule it for you when it creates your MSI. I did not schedule FindRelatedProducts in the sample I created for this reason.
Step 2: Add logic to handle out-of-order installations (installing version 2 then trying to install version 1)
The information provided in step 1 will allow your MSI to uninstall older versions of your MSI during the install process for newer versions. In order to be complete, you should also include information in your MSI to handle scenarios where a user attempts to install a newer version of your MSI and then install an older version afterwards (an out-of-order installation). This step is not strictly necessary, but including this information in your MSI allows you to provide a more user-friendly experience in the case of an out-of-order installation scenario.
Detecting an out-of-order installation requires authoring another entry in the Upgrade table that defines a property that will be set if a newer version of the MSI is found on the user's system. From the example, this looks like the following:
<Upgrade Id="!(loc.Property_UpgradeCode)"> <UpgradeVersion Minimum="$(var.ProductVersion)" OnlyDetect="yes" Property="NEWERVERSIONDETECTED" /></Upgrade>
Once you have defined the detection property, you need to decide how you want your MSI to behave in an out-of-order installation scenario and author an appropriate custom action. There are a couple of options:
A question that I have been asked in the past is why would an MSI want to immediately exit and return success instead of blocking and returning an error in an out-of-order installation scenario? The primary reason for this type of behavior is backwards compatibility for calling applications, particularly if the MSI is a redistributable component that can be shipped and installed as a part of other products. Here are a couple of examples of this type of scenario:
Step 3: Build version 1 and version 2 of your MSI
Creating version 1 of your MSI is as simple as running your standard build process - in WiX v3.0, this means you compile and link it with the WiX toolset. In order to create version 2 of your MSI, you must make the following changes to your setup authoring, then re-run your build process to create a new MSI:
In the example I created, I included scripts you can run on a system that has a build of WiX v3.0 installed in order to build 2 sets of MSIs:
Step 4: Test upgrade scenarios BEFORE YOU SHIP VERSION 1
This step is very important and in my past experience it has been too often ignored. In order to make sure that upgrade scenarios will behave the way you expect, you should test upgrades before you ship the first version of your MSI. There are some upgrade-related bugs that can be fixed purely by making fixes in version 2 or higher of your MSI, but there are some bugs that affect the uninstall of version 1 that must be fixed before you ship version 1. Once version 1 ships, you are essentially locked into the uninstall behavior that you ship with version 1, and that impacts major upgrade scenarios because Windows Installer performs an uninstall of version 1 behind the scenes during version 2 installation.
Here are some interesting scenarios to test:
When testing major upgrade scenarios, make sure to pay particular attention to custom actions in your MSI and assemblies that need to be installed to the GAC or the Win32 WinSxS store. Here are a few blog posts I've written in the past that contain examples of issues found during major upgrade testing:
Another more detailed example
While working on the sample for this blog post, I found the blog post at http://blogs.technet.com/alexshev/archive/2008/02/15/from-msi-to-wix-part-8-major-upgrade.aspx. This blog post contains more specific details about how Windows Installer behaves behind the scenes during a major upgrade, what information is required in an MSI for major upgrades, and how to map the information in the MSI rows/tables to WiX syntax. The example in that blog post was created with WiX v2.0 whereas the sample I posted uses WiX v3.0. The underlying concepts are the same, and the WiX syntax is only slightly different between v2.0 and v3.0. If you are interested in more detailed behind-the-scenes information about how major upgrades work, and/or if you are trying to implement a major upgrade that uses different settings than the ones presented in my example, I encourage you to check out this blog post as well.
<update date="3/12/2009"> Fixed broken link to the sample WiX source code for this post. </update>
PingBack from http://blog.a-foton.ru/index.php/2008/12/17/how-to-implement-build-and-test-a-windows-installer-major-upgrade-in-wix-v30/
Very good post and too the point!
Isn't there an automatic tester for such issues? (which are not applicative)
Hi Ran Davidovitz - I don't know of any existing automated testing tools for this type of upgrade scenario, but it would be possible to create this type of automation to make upgrade testing easier. If you run across any automation or create any yourself, please post another comment here so folks reading this blog post will be able to find it.
A while back, I wrote a blog post where I introduced a set of Visual Studio 2005 and 2008 project templates