Search code examples
wixwindows-installerburn

WiX bundle install and standalone MSI for upgrades


I have a WiX bundle that includes the .NET core runtime installer and my product MSI. If I don't tweak anything, I get two entries in the Add/Remove Programs list - one for the bundle and one for the product MSI. I have tried two approaches of showing only one but I run into some issue either way.

Approach #1 - Set MsiPackage attribute "Visible" to "no" in the bundle. This leaves a single entry in Add/Remove Programs (for the bundle).

The problem here is if they do an initial install with the bundle, but later only install the MSI to upgrade, they get 2 entries in the Add/Remove Programs list - the original bundle one and the new product one.

Approach #2 - Set Bundle attributes DisableRemove and DisableModify both to "yes" in the bundle. This gives a single Add/Remove Programs entry - this time for the product MSI, not the bundle.

The problem here is the following sequence:

  1. Install bundle version 10
  2. Uninstall ARP entry (product MSI)
  3. Install bundle version 9

That third step fails because the system sees a version 10 bundle still installed.

Our bundle is 30MB and our product is 3MB. I don't want to have to have every subsequent update download another bundle when I know .NET is already present and not necessary. So what approach can I use to install the bundle originally but later update with an MSI and not run into the issues above?

EDIT: The only approach I can think of is to have a custom action on uninstall which detects whether or not the MSI was dispatched via the bundle (as opposed to standalone) and if it is not, it then uses something like MsiEnumRelatedProducts() to find the product guid for the bundle and inline uninstalls that. Seems super messy and I'm not sure if it would even work or if that invocation would hit some kind of "installer already running" error.


Solution

  • I think the simplest solution here is to never distribute MSIs and create two versions of the bundle - one that only contains our package, and the other which contains our package plus the .NET runtime. Always mark the embedded MSI as visible=no and have the bundle's entry show up in ARP. This ensures bundles always update bundles, ARP shows the correct version, and that nothing ever gets left behind on an uninstall.

    I tried to implement a custom action on MSI uninstall to query the bundle's Upgrade Code and manually remove it. Unfortunately, WiX bundles do not show up to the system as normal products. So while I could manually parse the registry, the more robust APIs like MsiEnumRelatedProducts() cannot be used. Therefore, I think the bundle-of-one is my best solution at this time.