How To Remove Files and Folders when Uninstalling with WiX

Written by Alex Marin · May 27th, 2022

In some instances, when uninstalling an MSI, you may notice that some files and folders stay in the system and are not removed.

This can be seen in the example we portrayed in our article How To Embed CAB Files in MSI. There, we saw how to embed CAB files in an MSI with WiX Toolset and we created a simple MSI by using a basic WXS file.

If you tried that example and installed the MSI and then uninstalled it - you saw that the files still remained on the system.

In this article, we're going to show you how to sort that out. Coming up, we will have a look at some options that you have with WiX to remove files and folders during uninstallation, and also how you can do the same with Advanced Installer.

How to Remove Files with WiX?

WiX offers the possibility to remove files with the RemoveFile element inside a component declaration.

For example, if we have a look at our original WXS, it should look something like this:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1111-2222-3333-666666666666"
Name="My First Installer" Version="1.0.0.0" Manufacturer="Caphyon" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Hello, this is my test installer"/>
<MediaTemplate EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyFirstInstaller">
<Component Id="Files" Guid="11111111-2222-3333-4444-555555555555">
<File Id="File1" Source="Trace32.exe"/>
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="Feature1" Level="1" Title="First feature" Description="This is the one and only feature in this installation">
<ComponentRef Id="Files"/>
</Feature>
</Product>
</Wix>

As mentioned, the RemoveFile element must be added under a component parent, like this:

<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyFirstInstaller">
<Component Id="Files" Guid="11111111-2222-3333-4444-555555555555">
<File Id="File1" Source="Trace32.exe"/>
<RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
</Component>
</Directory>
</Directory>
</Directory>

This is configured so that all the files (“*.*”) inside our INSTALLDIR are deleted during uninstallation. You can specify only one file (“myfile.extension”) or a certain type of files by extension, using the wildcard character (“*.txt”).

The final WXS code will be:

<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" UpgradeCode="12345678-1111-2222-3333-666666666666"
Name="My First Installer" Version="1.0.0.0" Manufacturer="Caphyon" Language="1033">
<Package InstallerVersion="200" Compressed="yes" Comments="Hello, this is my test installer"/>
<MediaTemplate EmbedCab="yes" />
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLDIR" Name="MyFirstInstaller">
<Component Id="Files" Guid="11111111-2222-3333-4444-555555555555">
<File Id="File1" Source="Trace32.exe"/>
<RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
</Component>
</Directory>
</Directory>
</Directory>
<Feature Id="Feature1" Level="1" Title="First feature" Description="This is the one and only feature in this installation">
<ComponentRef Id="Files"/>
</Feature>
</Product>
</Wix>

Once we have the WXS created, let’s create the batch file to build the MSI:

"C:\Program Files (x86)\WiX Toolset v3.11\bin\candle.exe" test.wxs
"C:\Program Files (x86)\WiX Toolset v3.11\bin\light.exe" test.wixobj
@pause

Once you double-click the batch file, the MSI should be created.

Remove MSI file with WiX

If we install and uninstall the MSI, all the files should be removed during uninstallation and no files will remain in the system.

How to Remove Folders with WiX

To remove folders during the installation or uninstallation of an MSI, you have the option of using the RemoveFolder element. It works and behaves the same way as the RemoveFile element that we previously presented.

The steps are the same as when adding it to your WXS file.

But, the RemoveFolders element only works for directories created with the MSI database and with empty folders. This means that you must use the RemoveFile element to empty the folders first, and then the RemoveFolder element to delete the actual folder.

You may wonder - what about the folders that are created by the application after it is executed?

WiX has the option to add a RemoveFolderEX util extension element in your WXS. But adding this element is kind of tricky.

The RemoveFolderEX is a Custom Action that adds temporary rows to the RemoveFile table for each subfolder of the root specified in the WXS.

It has the characteristic that temporary rows must be written before the CostInitialize standard action, and MSI databases do not create properties for the directory hierarchy in your package until later, in the CostFinalize action. So, we need to get creative on how to add the RemoveFolderEx element in the WXS.

The easiest way to achieve this is to remember the directory we want to delete in the registry. Then, during the uninstallation - read the path from the registry and pass it to the RemoveFolderEx element. You can find a full step-by-step guide here: The WiX toolset's Remember Property pattern.

How to remove directories using VBScript Custom Action?

An alternative would be to create a Custom Action with a simple VBScript code to delete the unwanted remaining directories. This way, you don’t have to worry about empty directories.

1. Let’s create a simple VBScript that will delete the folder, in our case “C:\Program Files (x86)\MyFirstInstaller” (you can pass properties to VBScript if you don’t want to hardcode your custom actions).

Dim FSO, Folder
set FSO=CreateObject("Scripting.FileSystemObject")
Folder="C:\Program Files (x86)\MyFirstInstaller"
FSO.DeleteFolder(Folder)

In our case, the VBScript is called Sample.vbs and it’s placed near the WXS and batch file we previously created.

2. Adjust the WXS file to include the custom action. The code to add our Custom Action is:

<Binary Id='Sample.vbs' SourceFile='Sample.vbs' />
<CustomAction Id='Sample.vbs' VBScriptCall='' BinaryKey='Sample.vbs' Execute='deferred' Return='ignore'/>
<InstallExecuteSequence>
	<Custom Action='Sample.vbs' Before='InstallFinalize'>REMOVE~="ALL"</Custom>
	<ScheduleReboot Suppress="yes"/>
</InstallExecuteSequence>

Before moving forward, let’s see what the above configuration does:

2.1 We declare our binary for the custom action as Sample.vbs

2.2 We create a Custom Action called Sample.vbs

2.3 We declare the execution to be deferred and ignore the return code

2.4 We place it before the InstallFinalize sequence (because we are running a deferred custom action)

2.5 We tell the MSI to run the custom action only during the remove operation by adding the following property:

REMOVE~=”ALL”

2.6 We suppress the Reboot

3. Now, it’s time to build the MSI by running the make_msi.bat file that we previously created and test the scenario.

4. We can see that the folder is now deleted after the uninstallation of the package.

Remove folder with WiX

As previously mentioned, you need to be aware of what you are trying to achieve in terms of files and folders removal in your MSI. For demo purposes, we used a hardcoded VBScript, which is not a best practice.

An ideal script would have the ability to get the MSI directory variables to be able to correctly remove the directories during uninstallation – if the user selects to install the application in a different directory.

Another important aspect is when and how you declare your custom action to run. In our example, we are deleting folders in “Program Files”, meaning that we need to declare the custom as action to run as deferred.

How to Remove files and folders with Advanced Installer?

Advanced Installer makes it easy to delete all the files you are adding to your project automatically during uninstallation. You don’t need to worry about declaring anything inside the project.

However, if the application is creating additional files that you want to remove during the uninstallation, use the File Removal Operations that is included in Advanced Installer’s GUI.

If you are curious about how removing files and folders works in Advanced Installer, try it through our 30-day full featured trial.

To achieve this, follow these steps:

1. Navigate to the folder that contains the file you want to remove, right-click on it and select New File Operation - File Removal.

Advanced Installer File Removal

2. A new dialog will appear where you can specify a file name, select a certain file type that you want to be deleted, and also choose if the operation happens during the installation or uninstallation of the MSI.

You also have two more options: to Remove Empty Folders or Remove Non Empty Folders.

3. Make sure to save your changes by clicking “OK”.

Advanced Installer File Removal Dialog

4. If you want to delete an entire folder or clean up additional folders left by your application, you can right-click on the folder and choose Properties.

5. A new dialog will appear which will have the Operations tab. Click on it.

Advanced Installer Folder Operations

You can choose to delete the folder whether it’s empty or not and select when the removing action should occur, as well as additional conditions and the overwrite behaviour.

As you can see, Advanced Installer's GUI makes removal operations for files and folders a more seamless process.

Conclusion

And there you have it! Now you know how to remove files and folders when uninstalling with WiX, and have a few options to do so.

For direct access to the latest news, videos, and fresh HowTos and guides, join our mailing list to stay informed about the packaging industry: https://www.advancedinstaller.com/newsletter-subscribe.html

Let us know if there are any topics you'd like us to cover.

Get the most from packaging with Advanced Installer

Try the 30-day fully-featured edition absolutely free!

Advanced Installer Architect edition