tags:

views:

6415

answers:

3

Hello. When uninstalling my app, I'd like to configure the wix setup to remove all the files that were added after the original installation. It seems like the uninstaller removes only the directories and files that were originally installed from the MSI file and it leaves everything else that was added later in the app folder. In another words, I'd like to purge the directory when uninstalling. How do I do that?

thanks

+14  A: 

Use RemoveFile element with On="uninstall". Here's an example:

<Directory Id="CommonAppDataFolder" Name="CommonAppDataFolder">
  <Directory Id="MyAppFolder" Name="My">
    <Component Id="MyAppFolder" Guid="cc509cb7-c1a1-46cf-8c62-7cbb0017783c">
      <CreateFolder />
      <RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
    </Component>
  </Directory>
</Directory>

Update

It didn't work 100%. It removed the files, however none of the additional directories - the ones created after the installation - were removed. Any thoughts on that? – pribeiro

Unfortunately Windows Installer doesn't support deleting directories with subdirectories. In this case you have to resort to custom action. Or, if you know what subfolders are, create a bunch of RemoveFolder and RemoveFile elements.

Pavel Chuchuva
Thank you Pavel. However it didn't work 100%. It removed the files, however none of the additional directories - the ones created after the installation - were removed. Any thoughts on that?
pribeiro
Oh, neither the files under those directories were deleted.
pribeiro
I updated my answer to address your question.
Pavel Chuchuva
+4  A: 

To do this, I simply created a custom action to be called on uninstall.

The WiX code will look like this:

<Binary Id="InstallUtil" src="InstallUtilLib.dll" />

<CustomAction Id="DIRCA_TARGETDIR" Return="check" Execute="firstSequence" Property="TARGETDIR" Value="[ProgramFilesFolder][Manufacturer]\[ProductName]" />
<CustomAction Id="Uninstall" BinaryKey="InstallUtil" DllEntry="ManagedInstall" Execute="deferred" />
<CustomAction Id="UninstallSetProp" Property="Uninstall" Value="/installtype=notransaction /action=uninstall /LogFile= /targetDir=&quot;[TARGETDIR]\Bin&quot; &quot;[#InstallerCustomActionsDLL]&quot; &quot;[#InstallerCustomActionsDLLCONFIG]&quot;" />

<Directory Id="BinFolder" Name="Bin" >
 <Component Id="InstallerCustomActions" Guid="79902CE0-FDFD-4303-A063-D9249F49B1E7">
  <File Id="InstallerCustomActionsDLL" Name="SetupCA.dll" LongName="InstallerCustomActions.dll" src="InstallerCustomActions.dll" Vital="yes" KeyPath="yes" DiskId="1" Compressed="no" />
  <File Id="InstallerCustomActionsDLLCONFIG" Name="SetupCA.con" LongName="InstallerCustomActions.dll.Config" src="InstallerCustomActions.dll.Config" Vital="yes" DiskId="1" />
 </Component>
</Directory>

<Feature Id="Complete" Level="1" ConfigurableDirectory="TARGETDIR">
 <ComponentRef Id="InstallerCustomActions" />
</Feature>

<InstallExecuteSequence>
 <Custom Action="UninstallSetProp" After="MsiUnpublishAssemblies">$InstallerCustomActions=2</Custom>
 <Custom Action="Uninstall" After="UninstallSetProp">$InstallerCustomActions=2</Custom>
</InstallExecuteSequence>

The code for the OnBeforeUninstall method in InstallerCustomActions.DLL will look like this (in VB).

Protected Overrides Sub OnBeforeUninstall(ByVal savedState As System.Collections.IDictionary)
 MyBase.OnBeforeUninstall(savedState)

 Try
  Dim CommonAppData As String = Me.Context.Parameters("CommonAppData")
  If CommonAppData.StartsWith("\") And Not CommonAppData.StartsWith("\\") Then
   CommonAppData = "\" + CommonAppData
  End If
  Dim targetDir As String = Me.Context.Parameters("targetDir")
  If targetDir.StartsWith("\") And Not targetDir.StartsWith("\\") Then
   targetDir = "\" + targetDir
  End If

  DeleteFile("<filename.extension>", targetDir) 'delete from bin directory
  DeleteDirectory("*.*", "<DirectoryName>") 'delete any extra directories created by program
 Catch
 End Try
End Sub

Private Sub DeleteFile(ByVal searchPattern As String, ByVal deleteDir As String)
 Try
  For Each fileName As String In Directory.GetFiles(deleteDir, searchPattern)
   File.Delete(fileName)
  Next
 Catch
 End Try
End Sub

Private Sub DeleteDirectory(ByVal searchPattern As String, ByVal deleteDir As String)
 Try
  For Each dirName As String In Directory.GetDirectories(deleteDir, searchPattern)
   Directory.Delete(dirName)
  Next
 Catch
 End Try
End Sub
Friend Of George
A: 

Not an WIX expert, but could a possible (simpler?) solution to this be to run the Quiet Execution Custom Action which is part of the built in extensions of WIX?

Could run the rmdir MS DOS command with the /S and /Q options.

<Binary Id="CommandPrompt" SourceFile="C:\Windows\System32\cmd.exe" />

And the custom action doing the job is simple:

<CustomAction Id="DeleteFolder" BinaryKey="CommandPrompt" 
              ExeCommand='/c rmdir /S /Q "[CommonAppDataFolder]MyAppFolder\PurgeAppFolder"' 
              Execute="immediate" Return="check" />

Then you'll have to modify the InstallExecuteSequence as documented many places.

Update: Had issues with this approach. Ended up making a custom task instead, but still considers this a viable solution, but without getting the details to work.

tronda