Search code examples
wixbootstrapperburnwix3.11

WIX Burn upgrade removes ExePackages after installing new version


How can I prevent Wix burn from removing ExePackages during an upgrade install?

Background: I'm creating an installer using Wix 3.11 with a custom bootstrapper application, and multiple ExePackages and MsiPackages. Some of the ExePackages install dependencies that are unlikely to change between versions of our product. I'm trying to test an upgrade scenario before releasing the first version of the installer.

Here's an example of one of my ExePackages:

<ExePackage
    Id="InstallDependencyApp"
    DisplayName ="DependencyApp"
    SourceFile="$(var.InstallerApp.TargetPath)"
    CacheId="E1FFF6FF-0B84-41B4-982E-B8920DBA6A73"
    PerMachine="yes"
    DetectCondition="DependencyApp_InstalledVersion &gt;= DependencyApp_BundleVersion"
    InstallCommand="install dependencyApp [INSTALLCONFIG] [WixBundleLog_InstallDependencyApp]"
    UninstallCommand="uninstall dependencyApp [INSTALLCONFIG] [WixBundleLog_InstallDependencyApp]">
        <PayloadGroupRef Id="ExeDeps"/>
        <ExitCode Behavior="success" Value="0"/>
        <ExitCode Behavior="error" Value="-1"/>
</ExePackage>

I understand that during an upgrade, the Wix bootstrapper will install the new versions of all of the packages, and then trigger the silent uninstallation of the old bootstrapper.

What is happening in my case, is that the upgrade installer (appropriately) skips the ExePackages for the dependency installers, because the DetectCondition indicates that they are already installed. Then the uninstaller for the previous version runs, and removes the ExePackages, even though they are still needed as dependencies for the new version.

If the uninstall happened before the upgrade install, it would be okay, since the dependencies would be uninstalled and then reinstalled. But I don't think I can change when the uninstall happens in the chain.

I think I could work around this by putting some custom logic in the PlanPackageBegin listener in my bootstrapper, which would conditionally skip uninstalling packages with certain IDs in upgrade scenarios. That seems like a messy fix though. Is there a better way to configure my bundle to correctly handle these packages?


Solution

  • To enable ref-counting, declare a dependency provider for the package:

    <ExePackage>
      <dep:Provides Key="MyKey" Version="1.0.0.0" />
    </ExePackage>
    

    This means that when the package is installed, the bundle registers that provider and adds a reference count to the provider for itself. During upgrade, the new bundle will add its own reference to the provider. When the old bundle is uninstalled, it will see that there are still references and will only remove its reference instead of uninstalling the package.