web-dev-qa-db-ja.com

WiXをアンインストールするときにファイルを削除する

アプリケーションをアンインストールするときに、元のインストール後に追加されたすべてのファイルを削除するように Wix セットアップを構成したいと思います。アンインストーラーはMSIファイルから最初にインストールされたディレクトリとファイルのみを削除し、後でアプリケーションフォルダーに追加された他のすべてを残すようです。言い換えれば、アンインストール時にディレクトリを削除したいのです。それ、どうやったら出来るの?

75
pribeiro

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要素の束を作成します。

81
Pavel Chuchuva

RemoveFolderEx WiXのUtil拡張の要素を使用します。
このアプローチでは、すべてのサブディレクトリも削除されます( RemoveFile要素を直接使用 とは対照的)。この要素は、MSIデータベースのRemoveFileおよびRemoveFolderテーブルに一時行を追加します。

29
Alexey Ivanov

これを行うには、アンインストール時に呼び出されるカスタムアクションを作成しました。

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
12

@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」は使用できません。

9
Pierre

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を変更する必要があります。

更新:このアプローチには問題がありました。代わりにカスタムタスクを作成することになりましたが、これを実行可能なソリューションと見なしていますが、詳細を機能させることはできません。

7
tronda

これは、 @ 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とレジストリフォルダーの両方がシステムから削除されます。レジストリへのパスは、他のHiveおよび他の場所にあることに注意してください。

4
Eli