Though I’ve commented before about unnecessarily “nuking” whole registry keys, sometimes it’s what’s needed. The same applies to the file system: Sometimes apps create files and directories that weren’t part of the original installation. MSI makes it easy to remove files, including via wildcard. Individual directories can also be removed, but MSI doesn’t have support for wildcard directories or recursive directory trees. It’s easy to delete trees via custom action but tougher to do so while also handling rollback.
Thanks to Rob’s work on wixcontrib, the code to handling directory nuking was available. I took it with some improvements into WixUtilExtension in WiX v3.6 and it’s available with today’s build: 3.6.1321.0.
Use the RemoveFolderEx element as a child of a Component:
<util:RemoveFolderEx On=”uninstall” Property=”MyDirtyDirectory” />
There is one annoying restriction: RemoveFolderEx cannot be used directly on a directory defined in your installer. It’s an annoying chicken/egg problem. As adding directories and files to be deleted affects MSI’s file costing, RemoveFolderEx has to do its thing before costing. Unfortunately, MSI doesn’t set up properties for target directories until after costing is complete.
According to a poll both unscientific and informal, the most common use case is that the directory path is already written to a registry value anyway, for use by the installed application. See Rob’s blog post The WiX toolset’s “Remember Property” pattern for an example. As the AppSearch standard action sets the property well before costing begins, RemoveFolderEx works.
Quick implementation note: RemoveFolderEx works by recursing from the specified directory, adding temporary rows to the RemoveFile table for each subdirectory, one for the directory and one for the files in each directory. This is the pattern I described as “semi-custom actions” way back in 2007.