在 InstallValidate 之前安排 RemoveExistingProducts 自定义操作是不是可以?

Posted

技术标签:

【中文标题】在 InstallValidate 之前安排 RemoveExistingProducts 自定义操作是不是可以?【英文标题】:Is it ok to schedule RemoveExistingProducts custom action before InstallValidate?在 InstallValidate 之前安排 RemoveExistingProducts 自定义操作是否可以? 【发布时间】:2010-01-13 15:42:19 【问题描述】:

问题

我有一个 MSI,它在安装期间创建和启动 Windows 服务,并在卸载期间停止和删除该服务。这在自行安装和卸载时可以正常工作,但是在升级时,会显示 Files in Use 对话框(仅适用于 Vista 及更高版本,由于新的Restart Manager),表明该服务正在使用中.

背景

Files in Use 对话框在 InstallExecute 序列期间由 InstallValidate 自定义操作显示,该操作安排在 InstallValidate 自定义操作之前strong>RemoveExistingProducts 自定义操作;这意味着之前的版本还没有被卸载,所以应该显示Files in Use对话框

MSDN 文档指出 RemoveExistingProducts 动作必须安排在 InstallValidate 动作之后,我目前将 RemoveExistingProducts 动作安排在紧随其后InstallValidate 操作。

潜在解决方案

我想将 RemoveExistingProducts 自定义操作重新安排在 InstallValidate 自定义操作之前,以便之前的安装有机会在 InstallValidate 自定义操作之前停止并删除服务显示strong>正在使用的文件对话框。我尝试重新安排这些操作,它似乎可以正常工作,没有不良副作用(尽管日志仍然表明 InstallValidate 操作在 RemoveExistingProducts 操作之前执行),但是我对使用此解决方案犹豫不决,因为它违反了 MSDN 文档,并且可能存在我还没有看到的不利影响。

有人试过吗?我能想到的唯一其他选择是让新安装停止旧安装的服务,但这是不可取的,因为它要求安装具有有关它可以升级的所有旧安装的信息(停止此特定服务可能涉及更多而不仅仅是简单地调用服务管理器来停止它)。

【问题讨论】:

【参考方案1】:

我实施了问题中概述的潜在解决方案,将 RemoveExistingProducts 安排在 InstallValidate 之前。暂时没看到有什么问题,等安装好用了再发。

更新

我们的安装已经使用了一段时间,我没有发现任何不良影响。

【讨论】:

我尝试了<RemoveExistingProducts Before="InstallValidate" />,但它导致违反 ICE27:InstallExecuteSequence 表中的“RemoveExistingProducts”操作在错误的位置。当前:选择,正确:执行【参考方案2】:

它已经内置于 MSI / Windows Installer ... 唯一的问题是 .NET 安装程序类不使用 MSI“服务安装”功能。实际发生的情况是 MSI 正在尝试安装文件并使用刚刚复制的文件运行自定义命令(这就是 Visual Studio 放入 MSI 的所有内容)。

要解决此问题,您可以使用 ORCA 编辑 MSI 并将以下行添加到 ServiceControl 表中:

1   ServiceName 170     1   C__489628C5CC1144CB47F43E8BE7F3F31D

您可以从 FILES 表中查找的组件 ID ...我刚刚选择了主 EXE 文件的组件 ID。 170 是一个位图,告诉 Windows Installer 在安装和卸载时停止和删除服务。

这将为 .NET 安装程序添加服务扫清道路,您可以在通过自定义命令安装服务后使用 ServiceController 启动服务。

【讨论】:

【参考方案3】:

一个潜在的问题是,如果用户在 InstallValidate 期间取消(例如由于没有足够的磁盘空间或正在使用的文件)或在安装期间取消,回滚行为是什么。理想情况是应用程序状态与之前相同(例如安装了之前的应用程序)。您可能会放弃排序,尽管回滚可能是您可以不用的功能。

【讨论】:

这很奇怪,但我观察到(通过监视安装对话框并查看日志)InstallValidate 操作似乎仍然在 RemoveExistingProducts 之前执行 动作,即使它们按相反的顺序安排;不过,以这种方式安排它们确实解决了我的问题,即使我无法解释这种行为。此外,在我测试的场景中,回滚仍然正常运行。我必须根据您的建议更仔细地测试它。【参考方案4】:

我认为这将在不违反 MSDN 文档的情况下为您提供帮助,并避免将来出现任何问题。 设置条件“已安装或 PREVIOUSVERSIONSINSTALLED”,您也可以很好地升级,因为在 FindRelatedProducts 期间的 InstallValidate 操作之前设置了属性 PREVIOUSVERSIONSINSTALLED。 我不知道为什么,但是属性 PREVIOUSVERSIONSINSTALLED 没有记录在 MSDN 中,但它确实存在并且对我很有帮助。

【讨论】:

以上是关于在 InstallValidate 之前安排 RemoveExistingProducts 自定义操作是不是可以?的主要内容,如果未能解决你的问题,请参考以下文章

面向对象

如何在快速向 alamofire 发送请求之前安排数组

备忘录v0.27

备忘录v0.27

在主 Bundle 之前安排 RelatedBundle 操作

安排 cronjob 删除 X 天之前修改的文件