无法删除文件夹 WIX 安装程序
Can't delete folder WIX installer
我有一个由我的 WIX 安装程序安装的服务:
<Component Id="cmp_myService" Guid="{5FC8815E-33T8-4C3D-9654-849EE4CB1E22}">
<File Id="f_myService" Name="MyService.exe" Source="$(var.SourcePath)MyService.exe" KeyPath="yes" />
<ServiceInstall Id="si_myServiceInstall" Name="My Service" DisplayName="It is my service" Type="ownProcess" Interactive="yes" Start="auto" ErrorControl="normal" Description="Here is some description" />
<ServiceControl Id="sc_startStopMyService" Name="My Service" Start="install" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
另外,我有一个自定义操作 ca1_removeInstallDirOnUnsinstall
可以删除一个文件夹及其所有内容(MyService.exe
在这个文件夹中)
<Custom Action="ca1_removeInstallDirOnUnsinstall" After="DeleteServices"><![CDATA[REMOVE="ALL"]]></Custom>
我将此自定义操作安排到 运行,紧接在执行顺序中的 DeleteServices
操作之后。我假设此时 MyService.exe
应该停止并删除。但是我得到一个异常 Access to the path 'MyService.exe' is denied
,这意味着该服务尚未删除。为什么会发生这种情况,我的自定义操作应该安排在哪里以确保服务已被删除?
相关日志文件:
MSI (s) (64:3C) [08:42:32:597]: Doing action: StopServices
MSI (s) (64:3C) [08:42:32:597]: Note: 1: 2205 2: 3: ActionText
Action ended 8:42:32: UnpublishFeatures. Return value 1.
Action start 8:42:32: StopServices.
MSI (s) (64:3C) [08:42:32:597]: Doing action: DeleteServices
MSI (s) (64:3C) [08:42:32:597]: Note: 1: 2205 2: 3: ActionText
Action ended 8:42:32: StopServices. Return value 1.
Action start 8:42:32: DeleteServices.
MSI (s) (64:3C) [08:42:32:597]: Doing action: ca1_removeInstallDirOnUnsinstall
MSI (s) (64:3C) [08:42:32:597]: Note: 1: 2205 2: 3: ActionText
Action ended 8:42:32: DeleteServices. Return value 1.
MSI (s) (64:80) [08:42:32:597]: Invoking remote custom action. DLL: C:\windows\Installer\MSIA125.tmp, Entrypoint: RemoveInstallDirRecursively
MSI (s) (64:B8) [08:42:32:597]: Generating random cookie.
MSI (s) (64:B8) [08:42:32:597]: Created Custom Action Server with PID 6176 (0x1820).
MSI (s) (64:98) [08:42:32:644]: Running as a service.
MSI (s) (64:B4) [08:42:32:644]: Hello, I'm your 32bit Impersonated custom action server.
Action start 8:42:32: ca1_removeInstallDirOnUnsinstall.
SFXCA: Extracting custom action to temporary directory: C:\windows\Installer\MSIA125.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action CustomAction!CustomAction.FilesAndFoldersCustomAction.RemoveInstallDirRecursively
Access to the path 'MyService.exe' is denied.
InstallFinalize:DeleteServices
发生在[之前=11=]。我想 msiexec.exe
可能会在文件夹上锁定,以便在重大升级过程中重新安装,但我不确定(查找锁定使用:perfmon.exe, procexp64.exe).您可以将删除操作放在 InstallFinalize
之前(结束更改系统的提升操作)。这个位置应该有效,但不能保证。 “核对”整个文件夹不是好的做法。
最佳实践:通常你不应该删除整个文件夹(这是相当危险的 - 搞砸了,你最终可能会删除一半的计算机。说真的。我已经看到它发生了。不是用 MSI,而是用“清理 EXE”)。我会将日志文件放在用户配置文件或 %ProgramFiles%
之外的其他位置。或者可以使用 event log
甚至数据库上传到网上,以避免留下太多文件。
可接受的残留物:在我看来,不应尝试自动卸载日志文件和其他用户数据。为什么?它们是用户数据——换句话说:它们属于用户。你不能草率地删除它们吗?我会把数据留在原地,以防他们想要分析它们或重新安装应用程序(后者对于许可证密钥特别重要 - 你会留下它们吗?)。
WiX:WiX 有几个内置结构来帮助删除文件和文件夹。有内置的 MSI 变体(RemoveFile
, RemoveFolder
) that just delete files by wildcard or name. Then there is the RemoveFileEx
described by Bob Arnson (WiX developer team)。请阅读博客 post。我相信它可以递归地完成这项工作(所有子文件夹)。如你所知,我不经常使用这些结构因为我喜欢其他清理方法。坦率地说,我只是尝试在 PDF 或在线 KDB 文章中记录清理过程。
链接:
- wix - how to delete non-empty folder
- WIX - How to use RemoveFiles
我有一个由我的 WIX 安装程序安装的服务:
<Component Id="cmp_myService" Guid="{5FC8815E-33T8-4C3D-9654-849EE4CB1E22}">
<File Id="f_myService" Name="MyService.exe" Source="$(var.SourcePath)MyService.exe" KeyPath="yes" />
<ServiceInstall Id="si_myServiceInstall" Name="My Service" DisplayName="It is my service" Type="ownProcess" Interactive="yes" Start="auto" ErrorControl="normal" Description="Here is some description" />
<ServiceControl Id="sc_startStopMyService" Name="My Service" Start="install" Stop="both" Remove="uninstall" Wait="yes" />
</Component>
另外,我有一个自定义操作 ca1_removeInstallDirOnUnsinstall
可以删除一个文件夹及其所有内容(MyService.exe
在这个文件夹中)
<Custom Action="ca1_removeInstallDirOnUnsinstall" After="DeleteServices"><![CDATA[REMOVE="ALL"]]></Custom>
我将此自定义操作安排到 运行,紧接在执行顺序中的 DeleteServices
操作之后。我假设此时 MyService.exe
应该停止并删除。但是我得到一个异常 Access to the path 'MyService.exe' is denied
,这意味着该服务尚未删除。为什么会发生这种情况,我的自定义操作应该安排在哪里以确保服务已被删除?
相关日志文件:
MSI (s) (64:3C) [08:42:32:597]: Doing action: StopServices
MSI (s) (64:3C) [08:42:32:597]: Note: 1: 2205 2: 3: ActionText
Action ended 8:42:32: UnpublishFeatures. Return value 1.
Action start 8:42:32: StopServices.
MSI (s) (64:3C) [08:42:32:597]: Doing action: DeleteServices
MSI (s) (64:3C) [08:42:32:597]: Note: 1: 2205 2: 3: ActionText
Action ended 8:42:32: StopServices. Return value 1.
Action start 8:42:32: DeleteServices.
MSI (s) (64:3C) [08:42:32:597]: Doing action: ca1_removeInstallDirOnUnsinstall
MSI (s) (64:3C) [08:42:32:597]: Note: 1: 2205 2: 3: ActionText
Action ended 8:42:32: DeleteServices. Return value 1.
MSI (s) (64:80) [08:42:32:597]: Invoking remote custom action. DLL: C:\windows\Installer\MSIA125.tmp, Entrypoint: RemoveInstallDirRecursively
MSI (s) (64:B8) [08:42:32:597]: Generating random cookie.
MSI (s) (64:B8) [08:42:32:597]: Created Custom Action Server with PID 6176 (0x1820).
MSI (s) (64:98) [08:42:32:644]: Running as a service.
MSI (s) (64:B4) [08:42:32:644]: Hello, I'm your 32bit Impersonated custom action server.
Action start 8:42:32: ca1_removeInstallDirOnUnsinstall.
SFXCA: Extracting custom action to temporary directory: C:\windows\Installer\MSIA125.tmp-\
SFXCA: Binding to CLR version v4.0.30319
Calling custom action CustomAction!CustomAction.FilesAndFoldersCustomAction.RemoveInstallDirRecursively
Access to the path 'MyService.exe' is denied.
InstallFinalize:DeleteServices
发生在[之前=11=]。我想 msiexec.exe
可能会在文件夹上锁定,以便在重大升级过程中重新安装,但我不确定(查找锁定使用:perfmon.exe, procexp64.exe).您可以将删除操作放在 InstallFinalize
之前(结束更改系统的提升操作)。这个位置应该有效,但不能保证。 “核对”整个文件夹不是好的做法。
最佳实践:通常你不应该删除整个文件夹(这是相当危险的 - 搞砸了,你最终可能会删除一半的计算机。说真的。我已经看到它发生了。不是用 MSI,而是用“清理 EXE”)。我会将日志文件放在用户配置文件或 %ProgramFiles%
之外的其他位置。或者可以使用 event log
甚至数据库上传到网上,以避免留下太多文件。
可接受的残留物:在我看来,不应尝试自动卸载日志文件和其他用户数据。为什么?它们是用户数据——换句话说:它们属于用户。你不能草率地删除它们吗?我会把数据留在原地,以防他们想要分析它们或重新安装应用程序(后者对于许可证密钥特别重要 - 你会留下它们吗?)。
WiX:WiX 有几个内置结构来帮助删除文件和文件夹。有内置的 MSI 变体(RemoveFile
, RemoveFolder
) that just delete files by wildcard or name. Then there is the RemoveFileEx
described by Bob Arnson (WiX developer team)。请阅读博客 post。我相信它可以递归地完成这项工作(所有子文件夹)。如你所知,我不经常使用这些结构因为我喜欢其他清理方法。坦率地说,我只是尝试在 PDF 或在线 KDB 文章中记录清理过程。
链接:
- wix - how to delete non-empty folder
- WIX - How to use RemoveFiles