アプリケーションをアンインストールするときに、元のインストール後に追加されたすべてのファイルを削除するようにWixセットアップを構成したいと思います。アンインストーラーは、MSIファイルから最初にインストールされたディレクトリとファイルのみを削除し、後で追加されたすべてのものをアプリケーションフォルダーに残すようです。つまり、アンインストール時にディレクトリを削除したいのですが。それ、どうやったら出来るの?
回答:
On = "アンインストール"で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要素の束を作成します。
</Component>
コンパイルに失敗した後にディレクトリを追加するとFound orphaned Component 'MyAppFolder'.
RemoveFolderEx
WiXのUtil拡張機能の要素を使用します。
このアプローチでは、(要素を直接使用RemoveFile
するのではなく)すべてのサブディレクトリも削除されます。この要素は、一時的に行を追加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>
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」は使用できません。
これは、@ 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の専門家ではありませんが、これに対する可能な(より簡単な?)解決策は、WIXの組み込み拡張機能の一部であるQuiet Executionカスタムアクションを実行することでしょうか?
/ Sおよび/ Qオプションを指定してrmdirMSDOSコマンドを実行できます。
<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)ロックされたファイルを正しく処理しません