Al desinstalar mi aplicación, me gustaría configurar la instalación de Wix para eliminar todos los archivos que se agregaron después de la instalación original . Parece que el desinstalador elimina solo los directorios y archivos que se instalaron originalmente del archivo MSI y deja todo lo demás que se agregó más tarde en la carpeta de la aplicación. En otras palabras, me gustaría purgar el directorio al desinstalarlo. ¿Cómo puedo hacer eso?
fuente
</Component>
haber fallado una compilaciónFound orphaned Component 'MyAppFolder'.
Utilice el
RemoveFolderEx
elemento de la extensión Util en WiX.Con este enfoque, también se eliminan todos los subdirectorios (en lugar de usar el
RemoveFile
elemento directamente ). Este elemento añade filas temporales paraRemoveFile
yRemoveFolder
tabla en la base de datos de MSI.fuente
RemoveFile
yRemoveFolder
. Si desea mantener los archivos en una actualización, no puede utilizar todos estos enfoques.Para hacer esto, simplemente creé una acción personalizada que se llamará al desinstalar.
El código de WiX se verá así:
<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>
El código para el método OnBeforeUninstall en InstallerCustomActions.DLL se verá así (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
fuente
Aquí hay una variación de la sugerencia de @ tronda. Estoy eliminando un archivo "install.log" que se crea mediante otra acción personalizada durante la desinstalación:
<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>
Por lo que tengo entendido, no puedo usar "RemoveFile" porque este archivo se crea después de la instalación y no forma parte de un grupo de componentes.
fuente
Esta sería una respuesta más completa para la sugerencia de @Pavel , para mí está funcionando al 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>
Y, en el elemento Producto:
<Feature Id="Uninstall"> <ComponentRef Id="UninstallFolder" Primary="yes"/> </Feature>
Este enfoque establece un valor de registro con la ruta deseada de la carpeta que se eliminará en la desinstalación. Al final, tanto INSTALLFOLDER como la carpeta de registro se eliminan del sistema. Tenga en cuenta que la ruta al registro puede estar en otras colmenas y otras ubicaciones.
fuente
No soy un experto en WIX, pero ¿podría una solución posible (¿más simple?) Para esto ejecutar la acción personalizada de ejecución silenciosa que es parte de las extensiones integradas de WIX?
Podría ejecutar el comando rmdir MS DOS con las opciones / S y / Q.
<Binary Id="CommandPrompt" SourceFile="C:\Windows\System32\cmd.exe" />
Y la acción personalizada que hace el trabajo es simple:
<CustomAction Id="DeleteFolder" BinaryKey="CommandPrompt" ExeCommand='/c rmdir /S /Q "[CommonAppDataFolder]MyAppFolder\PurgeAppFolder"' Execute="immediate" Return="check" />
Luego, tendrá que modificar InstallExecuteSequence como se documenta en muchos lugares.
Actualización: tuve problemas con este enfoque. Terminó haciendo una tarea personalizada en su lugar, pero aún considera que esta es una solución viable, pero sin que los detalles funcionen.
fuente
cmd.exe
en su instalador. 2) Está realizando cambios en el sistema durante la generación del script 3) No hay opción de reversión 4) No maneja los archivos bloqueados correctamente