Robert Rouhani
Robert Rouhani

Reputation: 14688

Resolve property in WiX prior to util:RemoveFolderEx

I feel like what I'm trying to do here is very basic. The equivalent in NSIS took about 30 seconds to accomplish and was well documented.

My experience with WiX so far has been looking at very old documentation and mailing list posts. I've spent around 5 hours trying to install a single exe with vc_redist 2015.

I need to remove the C:\Program Files\App directory on uninstallation and am trying to use util:RemoveFolderEx to do so. The Property attribute of it requires the path to delete. So far I've tried:

After that I read that I need to set a property to [INSTALLFOLDER] to be able to use it elsewhere, so I did that with ARPINSTALLLOCATION. This still didn't work so I worked out how to get logs from the installer. It appears that the variable is getting set after RemoveFolderEx is called. Is there any way to reverse this or get the variable to be defined earlier?

So far I've tried changing the "After" property to a much earlier part of the process but it resulted in the variable never being set. I've also looked into just calling rmdir from a command prompt and the only thing I've been able to find is people saying "don't do it". I would also be open to calling RegistrySearch to grab the variable earlier if that's the only way. I just couldn't find any information on the internet about grabbing information from the Uninstall key when it's a GUID - or any information on how to move the rest of the information from the GUID key over to a Manufacturer/Product subkey

Relevant WXS snippet (the rest of it is essentially just the Visual Studio template):

<Product Id="$(var.ProductId)" Name="$(var.ProductName)" Language="1033" Version="$(var.ProductVersion)" Manufacturer="$(var.ProductManufacturer)" UpgradeCode="$(var.UpgradeCode)">
    <Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />

    ...
    <SetProperty Id="ARPINSTALLLOCATION" Value="[INSTALLFOLDER]" After="CostFinalize" />

    <Feature Id="ProductFeature" Title="App Installer" Level="1">
        <ComponentGroupRef Id="ProductComponents" />
    </Feature>

</Product>

<Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
        <Directory Id="$(var.PlatformProgramFilesFolder)">
            <Directory Id="INSTALLFOLDER" Name="App" />
        </Directory>
    </Directory>
</Fragment>

<Fragment>
    <ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
        ...
        <Component Id="RemoveInstallDir" Guid="7B2FE25A-B0D8-4308-834D-66CCB1F5F229">
            <CreateFolder />
            <util:RemoveFolderEx On="uninstall" Property="ARPINSTALLLOCATION" />
        </Component>
    </ComponentGroup>
</Fragment>

And the relevant log sections with some context lines:

MSI (s) (7C:58) [16:45:13:049]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSIFC67.tmp, Entrypoint: WixRemoveFoldersEx
MSI (s) (7C:68) [16:45:13:049]: Generating random cookie.
MSI (s) (7C:68) [16:45:13:050]: Created Custom Action Server with PID 24288 (0x5EE0).
MSI (s) (7C:50) [16:45:13:066]: Running as a service.
MSI (s) (7C:50) [16:45:13:067]: Hello, I'm your 32bit Impersonated custom action server.
Action start 16:45:13: WixRemoveFoldersEx.
WixRemoveFoldersEx:  Entering WixRemoveFoldersEx in C:\WINDOWS\Installer\MSIFC67.tmp, version 3.10.3007.0
WixRemoveFoldersEx:  Error 0x80070057: Missing folder property: ARPINSTALLLOCATION for row: wrfFACE66E9D000ACF7A46AACF6A7C5F32E
CustomAction WixRemoveFoldersEx returned actual error code 1603 but will be translated to success due to continue marking
MSI (s) (7C:68) [16:45:13:072]: Doing action: CostInitialize
MSI (s) (7C:68) [16:45:13:072]: Note: 1: 2205 2:  3: ActionText 
Action ended 16:45:13: WixRemoveFoldersEx. Return value 1.

...

Action start 16:45:13: CostFinalize.
MSI (s) (7C:68) [16:45:13:076]: Doing action: SetARPINSTALLLOCATION
MSI (s) (7C:68) [16:45:13:076]: Note: 1: 2205 2:  3: ActionText 
Action ended 16:45:13: CostFinalize. Return value 1.
MSI (s) (7C:68) [16:45:13:076]: PROPERTY CHANGE: Adding ARPINSTALLLOCATION property. Its value is 'C:\Program Files (x86)\Xearch\'.
Action start 16:45:13: SetARPINSTALLLOCATION.
MSI (s) (7C:68) [16:45:13:076]: Doing action: MigrateFeatureStates
MSI (s) (7C:68) [16:45:13:076]: Note: 1: 2205 2:  3: ActionText 
Action ended 16:45:13: SetARPINSTALLLOCATION. Return value 1.

Upvotes: 1

Views: 776

Answers (1)

PhilDW
PhilDW

Reputation: 20790

I suspect you are assuming that the values of properties are somehow automatically preserved between install and uninstall, but they are not. That's why you see errors like "missing folder property". To preserve the values use the WiX "remember property" pattern. If INSTALLFOLDER corresponds to that location then that's the one to use.

Two asides:

  1. ARPINSTALLLOCATION is set so that APIs can locate the primary install folder, so you or anyone to retrieve it. You'd typically use MsiGetProductInfo or equivalent passing the ProductCode and INSTALLPROPERTY_INSTALLLOCATION.

  2. Normally folders get removed automatically. The underlying problem you're trying to solve seems to be that the folder (and maybe some files in it) is left behind. I think "why is this folder left behind" is the interesting question to ask here.

Upvotes: 3

Related Questions