[wix] WiX 제거시 파일 제거

내 애플리케이션을 제거 할 때 원래 설치 후 추가 모든 파일을 제거 하도록 Wix 설정을 구성하고 싶습니다 . 제거 프로그램은 MSI 파일에서 원래 설치된 디렉토리와 파일 만 제거하고 나중에 추가 된 모든 파일은 응용 프로그램 폴더에 남겨 둡니다. 즉, 제거 할 때 디렉토리를 제거하고 싶습니다. 어떻게하나요?



답변

On = ” uninstall ” 과 함께 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 Installer는 하위 디렉터리가있는 디렉터리 삭제를 지원하지 않습니다. 이 경우 사용자 지정 작업에 의존해야합니다. 또는 하위 폴더가 무엇인지 알고있는 경우 RemoveFolder 및 RemoveFile 요소를 만듭니다.


답변

RemoveFolderExWiX에서 Util 확장의 요소를 사용합니다 .
이 접근 방식을 사용하면 모든 하위 디렉터리도 제거됩니다 ( element를 직접 사용RemoveFile 하는 것과 반대 ). 이 요소는 MSI 데이터베이스의 RemoveFileRemoveFolder테이블에 임시 행을 추가 합니다.


답변

이를 위해 간단히 제거 할 때 호출 할 사용자 지정 작업을 만들었습니다.

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>

InstallerCustomActions.DLL의 OnBeforeUninstall 메서드에 대한 코드는 다음과 같습니다 (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”을 사용할 수 없습니다.이 파일은 설치 후 생성되고 구성 요소 그룹의 일부가 아니기 때문입니다.


답변

이것은 @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>

그리고 제품 요소에서 :

<Feature Id="Uninstall">
    <ComponentRef Id="UninstallFolder" Primary="yes"/>
</Feature>

이 접근 방식은 제거시 삭제할 폴더의 원하는 경로로 레지스트리 값을 설정합니다. 마지막으로 INSTALLFOLDER와 레지스트리 폴더가 모두 시스템에서 제거됩니다. 레지스트리 경로는 다른 하이브 및 기타 위치에있을 수 있습니다.


답변

WIX 전문가는 아니지만 WIX 의 기본 제공 확장의 일부인 Quiet Execution Custom Action실행 하는 것이 가능한 (더 간단한?) 해결책이 될 수 있습니까?

/ S 및 / Q 옵션을 사용 하여 rmdir MS DOS 명령을 실행할 수 있습니다.

<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를 수정해야합니다.

업데이트 :
이 접근 방식에 문제가있었습니다. 대신 사용자 지정 작업을 작성했지만 여전히 이것이 실행 가능한 솔루션이라고 생각하지만 세부 사항이 작동하지 않습니다.


답변