Вопрос

При удалении моего приложения я хотел бы настроить Викс настройка для удаления всех добавленных файлов после оригинальной установки.Такое ощущение, что деинсталлятор удаляет из MSI-файла только те каталоги и файлы, которые были изначально установлены, а все остальное, что было добавлено позже, оставляет в папке приложения.Другими словами, я хотел бы очистить каталог при удалении.Как мне это сделать?

Это было полезно?

Решение

Использовать Элемент RemoveFile с Вкл.="удалить".Вот пример:

<Directory Id="CommonAppDataFolder" Name="CommonAppDataFolder">
  <Directory Id="MyAppFolder" Name="My">
    <Component Id="MyAppFolder" Guid="*">
      <CreateFolder />
      <RemoveFile Id="PurgeAppFolder" Name="*.*" On="uninstall" />
    </Component>
  </Directory>
</Directory>

Обновлять

Это не сработало на 100%.Он удалил файлы, однако ни один из дополнительных каталогов - те, которые созданы после установки - не были удалены.Есть мысли по этому поводу?- прибейро

К сожалению, установщик Windows не поддерживает удаление каталогов с подкаталогами.В этом случае вам придется прибегнуть к пользовательскому действию.Или, если вы знаете, что такое подпапки, создайте несколько элементов RemoveFolder и RemoveFile.

Другие советы

Для этого я просто создал настраиваемое действие, которое будет вызываться при удалении.

Код 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=&quot;[TARGETDIR]\Bin&quot; &quot;[#InstallerCustomActionsDLL]&quot; &quot;[#InstallerCustomActionsDLLCONFIG]&quot;" />

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

Насколько я понимаю, я не могу использовать " RemoveFile " потому что этот файл создается после установки и не входит в группу компонентов.

Я не эксперт по WIX, но может ли возможное (более простое?) решение этой проблемы запустить Пользовательское действие «Тихое выполнение» что является частью встроенных расширений 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, как описано во многих местах.

Обновлять:Были проблемы с этим подходом.Вместо этого я создал собственную задачу, но по-прежнему считает это жизнеспособным решением, но без того, чтобы детали работали.

Это был бы более полный ответ на предложение @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, и папка реестра удаляются из системы. Обратите внимание, что путь к реестру может быть в другом улье и других местах.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top