79 votes

Suppression de fichiers lors de la désinstallation de WiX

Lors de la désinstallation de mon application, j'aimerais configurer le WiX programme d'installation pour supprimer tous les fichiers qui ont été ajoutés après l'installation d'origine. Il semble que le programme de désinstallation ne supprime que les répertoires et les fichiers qui ont été installés à partir du fichier MSI et il laisse tout ce qui a été ajouté plus tard dans le dossier de l'application. En d'autres termes, je voudrais purger le répertoire lors de la désinstallation. Comment dois-je faire?

82voto

Pavel Chuchuva Points 12220

Utilisation RemoveFile élément avec Sur="désinstaller". Voici un exemple:

<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>

Mise à jour

Il ne fonctionnent pas à 100%. Il supprime les fichiers, cependant, aucun des répertoires supplémentaires - ceux créés après l'installation, ont été retirés. Des idées à ce sujet? – pribeiro

Malheureusement, programme d'installation de Windows ne prend pas en charge la suppression des répertoires avec des sous-répertoires. Dans ce cas, vous devez recourir à une action personnalisée. Ou, si vous savez ce que les sous-dossiers sont, de créer un groupe de RemoveFolder et RemoveFile éléments.

30voto

Alexey Ivanov Points 6564

Utiliser RemoveFolderEx élément d'Util extension dans WiX.
Avec cette approche, tous les sous-répertoires sont également supprimées (par opposition à l'aide d' RemoveFile élément directement). Cet élément ajoute temporaire lignes d' RemoveFile et RemoveFolder table dans la base de données MSI.

13voto

Friend Of George Points 359

Pour ce faire, j'ai simplement créé une action personnalisée pour être appelé sur désinstaller.

Le WiX code ressemblera à ceci:

<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>

Le code de la OnBeforeUninstall méthode InstallerCustomActions.DLL ressemblera à ceci (en 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

9voto

Pierre Points 559

Voici une variation sur @tronda de la suggestion. Je suis la suppression d'un fichier "install.journal" qui est créée par une autre Action Personnalisée, lors de la Désinstallation:

<Product>
    <CustomAction Id="Cleanup_logfile" Directory="INSTALLFOLDER"
    ExeCommand="cmd /C &quot;del install.log&quot;"
    Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />

    <InstallExecuteSequence>
      <Custom Action="Cleanup_logfile" Before="RemoveFiles" >
        REMOVE="ALL"
      </Custom>
    </InstallExecuteSequence>
</Product>

Comme je le comprends, je ne peux pas utiliser "RemoveFile" car ce fichier est créé après l'installation, et ne fait pas partie d'un Groupe de Composants.

7voto

tronda Points 1771

Pas un WIX expert, mais pourrait possible (simple?) la solution à cela est de lancer le Calme de l'Exécution de l'Action Personnalisée qui fait partie de la construction dans les extensions de WIX?

Pourriez exécuter la rmdir de commande MS-DOS avec le /S /Q options.

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

Et l'action personnalisée à faire le travail est simple:

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

Ensuite, vous devrez modifier le InstallExecuteSequence comme l'a documenté de nombreux endroits.

Mise à jour: Eu des problèmes avec cette approche. Fini par faire une tâche personnalisée à la place, mais considère toujours ce une solution viable, mais sans obtenir les détails de travailler.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X