アプリケーションをアンインストールするときに、元のインストール後に追加されたすべてのファイルを削除するように 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要素の束を作成します。
RemoveFolderEx
WiXのUtil拡張の要素を使用します。
このアプローチでは、すべてのサブディレクトリも削除されます( RemoveFile
要素を直接使用 とは対照的)。この要素は、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>
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 "del install.log""
Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="Cleanup_logfile" Before="RemoveFiles" >
REMOVE="ALL"
</Custom>
</InstallExecuteSequence>
</Product>
私の知る限り、このファイルはインストール後に作成され、コンポーネントグループの一部ではないため、「RemoveFile」は使用できません。
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を変更する必要があります。
更新:このアプローチには問題がありました。代わりにカスタムタスクを作成することになりましたが、これを実行可能なソリューションと見なしていますが、詳細を機能させることはできません。
これは、 @ 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および他の場所にあることに注意してください。