Aaron Stebner's WebLog

Thoughts about setup and deployment issues, WiX, XNA, the .NET Framework and Visual Studio

Assemblies may be missing from the GAC or WinSxS cache after an MSI major upgrade

Assemblies may be missing from the GAC or WinSxS cache after an MSI major upgrade

Rate This
  • Comments 8

I recently read about an issue that affects Windows Installer products that use major upgrades and also install assemblies to the GAC or the WinSxS component store using the MsiAssembly and MsiAssemblyName tables.  This issue is documented in the Microsoft Knowledge Base article at http://support.microsoft.com/kb/905238.

To summarize the issue, if you build an MSI that installs assemblies and includes major upgrade functionality, and then build a new version of the MSI that invokes a major upgrade, you may see the assemblies removed from the GAC or the WinSxS store after the major upgrade completes.  This happens if you do not change the assembly version for your assemblies and have not scheduled the RemoveExistingProducts action to occur after the InstallFinalize action.

If you are running into this issue with your MSI, you can workaround this issue in one of the following 2 ways:

  1. Increment the assembly version number for each of your assemblies every time you deliver a new MSI that will be installed via a major upgrade
  2. Schedule the RemoveExistingProducts action to occur after the InstallFinalize action in your MSI

If you change the scheduling, you do not necessarily need to increment the assembly version number for each of your assemblies.

One important note here - the sample WiX files for the Q and Z sample applications that ship in the Windows Media Center SDK for Windows Vista are susceptible to this problem.  I have updated the downloadable WiX v3.0 projects for the Q application (that can be downloaded from this location and that is described here) and the Z application (that can be downloaded from this location and that is described here) to address this.  The specific change I made in q.wxs and z.wxs implements the 2nd option listed above by changing this line in each WXS file:

<RemoveExistingProducts After="InstallInitialize" />

To this:

<RemoveExistingProducts After="InstallFinalize" />

If you have the Media Center SDK installed and want to make this fix for the WiX v2.0 files that are installed as part of the SDK, you can make equivalent changes to the versions of q.wxs and z.wxs included there.

  • Having RemoveExistingProducts after InstallFinalize comes with its own set of issues. It's not in the scripted part of the install, so if that REP uninstall fails and rolls back then you're left with both old and new products on the system. When REP is in the scripted part a roll back in the upgraded install and in the remove of the older one restore the system to its original state. The after InstallFinalize behavior is documented as "If the removal of the old application fails, then the installer only rolls back the uninstallation of the old application." but perhaps the consequences of that (leaving both old and new on the system) aren't quite so obvious. Since a repair of the product will install the missing assemblies anyway, my vote for the least-dangerous course would be to keep REP in the safest place - just after InstallInitialize.

  • Hi PhilDWilson - I'm not sure I agree that the least dangerous course is to leave RemoveExistingProducts before InstallInitialize.  This can cause your product assemblies to be not installed correctly in major upgrade scenarios, and then your users have to figure out that they will need to run a repair to fix it.  I understand the possible risk of the RemoveExistingProducts uninstall failing and leaving an extra copy of the product on the system, but that seems less invasive than leaving an install with missing assemblies.

    Overall, the cleanest solution is to update assembly versions for each major upgrade, but I know that is not always feasible for every software project for various reasons.

  • It's a judgement call, yes, but I often ask the question "what's the worst that that can happen". In this case, imagine a help desk trying to solve the problem of having both old and new products on the system, conflicting with each other, services all mixed up, COM registration all mixed up etc because one product was supposed to replace the other, not co-exist with it. Now imagine a help desk call where the answer is "right-click the MSI file and choose repair", and that call may not have even been necessary in the first place if a shortcut invoked the repair. So we'll agree to disagree on this one ;=)

  • Hi PhilDWilson - Your help desk call analogy is a useful question to ask in scenarios such as this, thank you for providing this example.

    I do want to point out, however, that leaving RemoveExistingProducts before InstallFinalize and doing a major upgrade of an MSI that includes assemblies with the same assembly version is guaranteed to result in missing assemblies.  The other case (putting RemoveExistingProducts after InstallFinalize and having the old product uninstall fail) might fail, but is not guaranteed to cause problems like the other scenario.  The help desk people may have to dig a bit deeper in this latter case, but I think the frequency of calls may be less with the recommendation in this blog post.

    That is a trade-off that each setup developer needs to weigh for their own product though, and my blog post should be taken only as a recommendation, not as the only option to approach this issue.

  • I ran into an interesting scenario related to Windows Installer major upgrades recently and I wanted

  • It's unclear from reading the KB article and your post if this issue would still apply if the File Version of the assembly was incremented and the FileVersion was set in the MsiAssemblyName table, or if it only applies when the assemblies are exactly the same and thus would not otherwise need be copied by the new package.  Do you have any idea?

  • Hi Jlevine - The FileVersion value is used when doing in-place upgrades of assemblies (for example, when applying a patch to an installed product) as described at http://msdn2.microsoft.com/en-us/library/Aa372360.aspx.

    However, my understanding is that the issue described in this blog and the KB article at http://support.microsoft.com/kb/905238 happens if the assembly identity is the same, which happens if the AssemblyVersion attribute is the same in both the old and the new version of your MSI.

    My understanding could be wrong though, so it may be worth trying a test major upgrade scenario where you only update the assembly's FileVersion to see how it behaves.

  • When I create an MSI-based installer, one of the things I typically include in the setup authoring is

Page 1 of 1 (8 items)
Leave a Comment
  • Please add 4 and 2 and type the answer here:
  • Post