Supprimer des fichiers lors de la désinstallation de WiX
lors de la désinstallation de mon application, je voudrais configurer le Wix setup pour supprimer tous les fichiers qui ont été ajoutés après l'installation originale . Il semble que le désinstalleur ne supprime que les répertoires et les fichiers qui ont été installés à l'origine à partir du fichier MSI et il laisse tout le reste qui a été ajouté plus tard dans le dossier d'application. En d'autres termes, j'aimerais purger le répertoire lors de la désinstallation. Comment dois-je faire?
6 réponses
Utiliser RemoveFile élément avec=" désinstaller ". Voici un exemple:
<Directory Id="CommonAppDataFolder" Name="CommonAppDataFolder">
<Directory Id="MyAppFolder" Name="My">
<Component Id="MyAppFolder" Guid="*">
<CreateFolder />
<RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
</Component>
</Directory>
</Directory>
mise à Jour
ça n'a pas marché à 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 Windows Installer ne supporte pas la suppression de répertoires avec des sous-répertoires. Dans ce cas, vous devez recourir à une action personnalisée. Ou, si vous savez ce que sont les sous-dossiers, créez un tas D'éléments RemoveFolder et RemoveFile.
Utilisation RemoveFolderEx
élément d'Util extension dans WiX.
Avec cette approche, tous les sous-répertoires sont également supprimés (par opposition à utilisant RemoveFile
élément directement ). Cet élément ajoute des lignes temporaires aux tables RemoveFile
et RemoveFolder
de la base de données MSI.
Pour ce faire, j'ai simplement créé une action personnalisée pour être appelé sur désinstaller.
le code WiX 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="[TARGETDIR]\Bin" "[#InstallerCustomActionsDLL]" "[#InstallerCustomActionsDLLCONFIG]"" />
<Directory Id="BinFolder" Name="Bin" >
<Component Id="InstallerCustomActions" Guid="*">
<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 pour la méthode OnBeforeUninstall dans 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
voici une variante de la suggestion de @tronda. Je supprime 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 "del install.log""
Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="Cleanup_logfile" Before="RemoveFiles" >
REMOVE="ALL"
</Custom>
</InstallExecuteSequence>
</Product>
autant que je sache, je ne peux pas utiliser" RemoveFile " parce que ce fichier est créé après l'installation, et ne fait pas partie d'un groupe de composants.
pas un expert WIX, mais pourrait-il une possible (plus 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?
pourrait exécuter la commande rmdir MS DOS avec les options /S et /Q.
<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" />
, Alors vous devrez modifier le InstallExecuteSequence comme documenté de nombreux endroits.
mise à Jour: Eu des problèmes avec cette approche. A fini par faire une tâche sur mesure à la place, mais considère toujours que c'est une solution viable, mais sans obtenir les détails pour travailler.
ce serait une réponse plus complète pour @Pavel suggestion, pour moi ça marche à 100%:
<Fragment Id="FolderUninstall">
<?define RegDir="SYSTEM\ControlSet001\services\[Manufacturer]:[ProductName]"?>
<?define RegValueName="InstallDir"?>
<Property Id="INSTALLFOLDER">
<RegistrySearch Root="HKLM" Key="$(var.RegDir)" Type="raw"
Id="APPLICATIONFOLDER_REGSEARCH" Name="$(var.RegValueName)" />
</Property>
<DirectoryRef Id='INSTALLFOLDER'>
<Component Id="UninstallFolder" Guid="*">
<CreateFolder Directory="INSTALLFOLDER"/>
<util:RemoveFolderEx Property="INSTALLFOLDER" On="uninstall"/>
<RemoveFolder Id="INSTALLFOLDER" On="uninstall"/>
<RegistryValue Root="HKLM" Key="$(var.RegDir)" Name="$(var.RegValueName)"
Type="string" Value="[INSTALLFOLDER]" KeyPath="yes"/>
</Component>
</DirectoryRef>
</Fragment>
et, sous l'élément de produit:
<Feature Id="Uninstall">
<ComponentRef Id="UninstallFolder" Primary="yes"/>
</Feature>
cette approche définit une valeur de registre avec le chemin désiré du dossier à supprimer lors de la désinstallation. À la fin, les deux fichiers INSTALLFOLDER et registry sont supprimés du système. Notez que le chemin vers le Registre peut être à d'autres ruches et d'autres endroits.