Search code examples
installationwixwindows-installerupgrade

MSI InstallFinalize ARP removal condition


I'm trying to configure WiX to build an installer so that I can activate Features via Properties provided by the commandline and migrate them to the next upgrade.

When trying to do a MajorUpgrade with my WiX-installer the upgrade does not remove the previous version from the ARP-Menü. Every other Feature/Component seems to be removed before the reinstall (the log lists them). This problem only occurs if I activated a feature during the previous version via a Property provided by the commandline.

ARP-entry of v1 gets removed:

msiexec /L*v install.log /i installerv1.msi
msiexec /L*v install.log /i installerv2.msi

ARP-entry of v1 does not get removed:

msiexec /L*v install.log /i installerv1.msi EXTRAFEATURE=true
msiexec /L*v install.log /i installerv2.msi EXTRAFEATURE=true

alternatively

msiexec /L*v install.log /i installerv1.msi EXTRAFEATURE=true
msiexec /L*v install.log /i installerv2.msi

(The ProductCode, PackageCode and Product Version differ between v1 and v2, the UpgradeCode stays the same)

Simplified WiX config:

<Product Id="$(var.CPACK_WIX_PRODUCT_GUID)"
    Name="$(var.CPACK_PACKAGE_NAME)"
    Language="1031"
    Version="$(var.CPACK_PACKAGE_VERSION)"
    Manufacturer="$(var.CPACK_PACKAGE_VENDOR)"
    UpgradeCode="$(var.CPACK_WIX_UPGRADE_GUID)">
    
    <Package InstallerVersion="301"
        InstallScope="perMachine"
        Compressed="yes"
        Description="$(var.CPACK_PACKAGE_NAME)"
        Keywords="!(loc.PackageKeywords)"
        Comments="!(loc.PackageComments)"/>

    <MajorUpgrade
        Schedule="afterInstallValidate"
        AllowSameVersionUpgrades="yes"
        DowngradeErrorMessage="!(loc.DowngradeErrorMessage)"/>

    <FeatureRef Id="ProductFeature"/>
    <FeatureRef Id="ExtraFeature"/>

    <Property Id="EXTRAFEATURE" Secure="yes"/>
    <Feature Id="ExtraFeature" Level="0">
        <Condition Level="1">EXTRAFEATURE</Condition>
        <ComponentRef Id="ExtraFeature"/>
    </Feature>
    
    ...
</Product>

Looking into the log I only see one difference: The InstallInitialize step does not trigger the generation of the script to remove the ARP-entry.

Working example:

MSI (s) (14:10) [10:24:20:422]: Doing action: InstallInitialize
Aktion 10:24:20: InstallInitialize. 
Aktion gestartet um 10:24:20: InstallInitialize.
MSI (s) (14:10) [10:24:20:423]: Machine policy value 'AlwaysInstallElevated' is 0
MSI (s) (14:10) [10:24:20:423]: User policy value 'AlwaysInstallElevated' is 0
Aktion 10:24:20: GenerateScript. Für folgende Aktion werden Skriptvorgänge generiert:
GenerateScript: InstallInitialize
MSI (s) (14:10) [10:24:20:429]: PROPERTY CHANGE: Deleting ProductToBeRegistered property. Its current value is '1'.
MSI (s) (14:10) [10:24:20:430]: Note: 1: 2205 2:  3: Class 
MSI (s) (14:10) [10:24:20:430]: Note: 1: 2228 2:  3: Class 4: SELECT `CLSID` FROM `Class` WHERE `Icon_`=? AND `Class`.`Attributes`=1 
MSI (s) (14:10) [10:24:20:430]: Note: 1: 2205 2:  3: Class 
MSI (s) (14:10) [10:24:20:430]: Note: 1: 2228 2:  3: Class 4: SELECT `Component`,`CLSID` FROM `Component`,`Class` WHERE `Component`=`Component_` AND `Icon_`=? AND  (`Component`.`Installed` <> 0 AND `Component`.`Action` <> 0) 
MSI (s) (14:10) [10:24:20:430]: Note: 1: 2205 2:  3: Extension 
MSI (s) (14:10) [10:24:20:430]: Note: 1: 2228 2:  3: Extension 4: SELECT `Component`,`Extension` FROM `Component`,`Extension`,`ProgId` WHERE `Component`.`Component`=`Extension`.`Component_` AND `ProgId`.`ProgId`=`Extension`.`ProgId_` AND `ProgId`.`Icon_`=? AND  (`Component`.`Installed` <> 0 AND `Component`.`Action` <> 0) 
MSI (s) (14:10) [10:24:20:430]: 'ProductIcon.ico' icon will be removed.
Aktion beendet um 10:24:20: InstallInitialize. Rückgabewert 1.

Not-working example:

MSI (s) (74:94) [09:50:04:656]: Doing action: InstallInitialize
Aktion 09:50:04: InstallInitialize. 
Aktion gestartet um 09:50:04: InstallInitialize.
MSI (s) (74:94) [09:50:04:658]: Machine policy value 'AlwaysInstallElevated' is 0
MSI (s) (74:94) [09:50:04:658]: User policy value 'AlwaysInstallElevated' is 0
Aktion beendet um 09:50:04: InstallInitialize. Rückgabewert 1.

In the docs for InstallFinalize (https://learn.microsoft.com/en-us/windows/win32/msi/installfinalize-action) I found this description:

If it is detected that the product is marked for complete removal, operations are automatically added to the script to remove the Add/Remove Programs in the Control Panel information for the product, to unregister and unpublish the product, and to remove the cached local database from %WINDOWS%, if it exists.

I cannot find any documentation regarding the condition when the ARP-entry gets removed. Why does adding the feature prevent the triggering of the ARP-removal?


Solution

  • The feature is disabled, so it's not being removed.

    http://www.joyofsetup.com/2008/05/16/make-sure-features-are-always-enabled-so-they-can-be-removed/