При удалении моего приложения я хотел бы настроить Wix так , чтобы удалить все файлы, которые были добавлены после первоначальной установки . Похоже, что деинсталлятор удаляет только каталоги и файлы, которые были изначально установлены из файла MSI, и оставляет все остальное, что было добавлено позже, в папке приложения. Другими словами, я хотел бы очистить каталог при удалении. Как я могу это сделать?
84
</Component>
Found orphaned Component 'MyAppFolder'.
Используйте
RemoveFolderEx
элемент из расширения Util в WiX.При таком подходе все подкаталоги также удаляются (в отличие от использования
RemoveFile
element напрямую ). Этот элемент добавляет временные строкиRemoveFile
иRemoveFolder
таблицу в базу данных MSI.источник
RemoveFile
иRemoveFolder
. Если вы хотите сохранить файлы при обновлении, вы не можете использовать все эти подходы.Для этого я просто создал настраиваемое действие, которое будет вызываться при удалении.
Код WiX будет выглядеть так:
<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>
Код метода OnBeforeUninstall в InstallerCustomActions.DLL будет выглядеть следующим образом (в 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
источник
Вот вариант предложения @tronda. Я удаляю файл install.log, который создается другим настраиваемым действием во время удаления:
<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>
Насколько я понимаю, я не могу использовать RemoveFile, потому что этот файл создается после установки и не является частью группы компонентов.
источник
Это был бы более полный ответ на предложение @Pavel , для меня он работает на 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>
И в элементе Product:
<Feature Id="Uninstall"> <ComponentRef Id="UninstallFolder" Primary="yes"/> </Feature>
Этот подход устанавливает значение реестра с желаемым путем к папке, которая будет удалена при удалении. В конце и INSTALLFOLDER, и папка реестра удаляются из системы. Обратите внимание, что путь к реестру может находиться в другом улье и других местах.
источник
Не эксперт WIX, но может ли возможным (более простым?) Решением этой проблемы запустить настраиваемое действие Quiet Execution, которое является частью встроенных расширений WIX?
Можно запустить команду rmdir MS DOS с параметрами / S и / Q.
<Binary Id="CommandPrompt" SourceFile="C:\Windows\System32\cmd.exe" />
А настраиваемое действие, выполняющее эту работу, простое:
<CustomAction Id="DeleteFolder" BinaryKey="CommandPrompt" ExeCommand='/c rmdir /S /Q "[CommonAppDataFolder]MyAppFolder\PurgeAppFolder"' Execute="immediate" Return="check" />
Затем вам придется изменить InstallExecuteSequence, как описано во многих местах.
Обновление: были проблемы с этим подходом. Вместо этого закончил создание настраиваемой задачи, но по-прежнему считает это жизнеспособным решением, но не заставляет детали работать.
источник
cmd.exe
в свой установщик. 2) Вы вносите изменения в систему во время генерации скрипта 3) Нет возможности отката 4) Некорректно работает с заблокированными файлами