Wix自定义卸载操作 - 如何在msi删除文件之前运行

Fra*_*čik 3 installation windows-installer wix wix3.7

我有一个自定义操作,将文件添加到安装目录.卸载程序时,另一个自定义操作会尝试删除这些文件,以便删除安装目录.

问题是我的自定义卸载操作删除标准安装文件运行,因此安装目录保留在那里,尽管它是空的.

配置看起来类似于:

<CustomAction Id="AddFilesAction" BinaryKey="installerActions" DllEntry="AddFiles" Execute="deferred" Return="check" Impersonate="no" />
<CustomAction Id="CleanupAction" BinaryKey="installerActions" DllEntry="Cleanup" Execute="deferred" Return="check" Impersonate="no" />

<InstallExecuteSequence>
  <Custom Action="CleanupAction" Before="InstallFiles">Installed</Custom>
  <Custom Action="AddFilesAction" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
Run Code Online (Sandbox Code Playgroud)

我可以在CleanupActionmsi开始删除安装文件之前运行,以便自定义文件已被删除,msi可以删除主安装目录吗?

zet*_*t42 6

问题是我的自定义卸载操作在删除标准安装文件后运行

那是因为你之前已经安排了它InstallFiles,这是RemoveFiles标准之后InstallExecuteSequence.您还可以在Orca或InstEd等编辑器中打开MSI文件,并查看该InstallExecuteSequence表.按Sequence列对其进行排序以查看执行顺序.

我可以在msi开始删除安装文件之前运行CleanupAction

当然,只是安排它RemoveFiles:

<Custom Action="CleanupAction" Before="RemoveFiles">
    (REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)
</Custom>
Run Code Online (Sandbox Code Playgroud)

编辑:在SteinÅsmul让我意识到这一点之后,我也改进了自定义动作条件.有关详细推理,请参阅他的答案.


如果您还不知道,WiX已经支持删除应用程序生成的文件,这些文件可能会替换您的自定义操作.它以RemoveFileutil:RemoveFolderEx元素的形式出现.

如果这些不能满足您的需求,那么您仍然需要自定义操作,我建议RemoveFile在运行时为要删除的文件添加临时记录(在立即自定义操作中!).这为您提供了使用MSI引擎进行实际文件删除的好处,即,如果用户决定取消卸载或发生错误,则自动回滚.我过去曾经这样做过(之前RemoveFolderEx发明过),所以如果你需要更多信息,可以问另一个问题.


Ste*_*mul 5

简短回答:您的条件和顺序似乎是错误的。请安排您的清理自定义操作在之前运行,RemoveFiles并可能设置更好的条件以使该操作仅在需要时运行(而不是在意外的设置模式下)。下面我建议(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)。如果您使用此条件,请彻底测试。这种情况解释如下

快速样品

<InstallExecuteSequence>
  <Custom Action="CleanupAction" 
          Before="RemoveFiles">(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)</Custom>
</InstallExecuteSequence>
Run Code Online (Sandbox Code Playgroud)

请务必阅读以下详细信息。您可能还想收紧复制文件操作的条件 - 因为否则它也会在主要升级时运行 - 这可能是也可能不是您想要的。


自定义操作替代方案如果可以,请避免自定义操作- 一些自定义操作问题的总结 - 它们很严重)。自定义操作是部署失败的主要原因。你确定你需要它们吗?通常还有其他方法可以使用内置的 MSI 功能或 WiX 特定的构造来实现您在自定义操作中实现的内容。常见的例子是:安装服务、删除文件、更新 XML 文件或 INI 文件等......但有时自定义操作是必要的 - 显然。Zett42 已经写了很好的替代方案,所以我不会在这里重复 - 请检查他/她的答案。


RemoveFiles:这里还有更多问题 - 我将在下面尝试描述这些问题 - 但是在标准操作RemoveFiles运行时会卸载文件。换句话说,您需要安排清理自定义操作在InstallExecuteSequence.


条件:您的情况Installed为您清理的自定义操作将在自定义操作运行modifyrepair并且minor upgrade patching除了uninstallmajor upgrade initiated uninstalls。这很可能不是您想要的。要指定仅在卸载时运行,最普通的条件是REMOVE~="ALL"。这将使清理发生在手动启动的卸载以及主要升级启动的卸载(我认为不是您想要的)时。您可以尝试(REMOVE~="ALL") AND (NOT UPGRADINGPRODUCTCODE)(仅在常规卸载时运行 - 而不是在主要升级卸载时运行)。


提示:条件很容易搞砸 - 即使对于有经验的 WiX / MSI 用户也是如此。一些可能有帮助的资源:


一些进一步的链接(供参考)

  • 您需要更改您的产品 G​​UID 才能对您的软件包进行重大升级。您是否仅使用 [次要升级](https://msdn.microsoft.com/en-us/library/windows/desktop/aa370037(v=vs.85).aspx)?[查询机器以确定安装了哪些 MSI 包(以查找产品 GUID)](/sf/answers/2095629861/) 相对容易 - 如果您的 AD 设置正确,即使是远程。[这是从远程机器检索升级代码的简介](/sf/answers/3264596681/)。 (2认同)