是否可以在InstallValidate 之前安排RemoveExistingProducts 自定义操作?
-
20-09-2019 - |
题
问题
我有一个 MSI,它可以在安装过程中创建和启动 Windows 服务,并在卸载过程中停止和删除该服务。这在单独安装和卸载时工作正常,但在升级时, 使用中的文件 显示对话框(仅在 Vista 及更高版本上,因为新的 重启管理器),表明该服务正在使用中。
背景
这 使用中的文件 期间会显示对话框 安装执行 序列由 安装验证 自定义操作,立即安排在 删除现有产品 自定义操作;这意味着之前的版本还没有被卸载,所以 使用中的文件 对话 应该 被显示。
MSDN 文档表明 删除现有产品 行动必须安排在 安装验证 行动,我目前有 删除现有产品 立即安排的行动 安装验证 行动。
潜在的解决方案
我想重新安排 删除现有产品 紧接在之前的自定义操作 安装验证 自定义操作,以便以前的安装有机会在安装之前停止并删除服务 使用中的文件 显示对话框。我尝试重新安排操作,它似乎工作正常,没有不良副作用(尽管日志仍然表明 安装验证 动作在之前执行 删除现有产品 操作),但我对使用此解决方案犹豫不决,因为它违反了 MSDN 文档,并且可能会产生我尚未看到的不利影响。
有人试过这个吗?我能想到的唯一的其他选择是让新安装停止旧安装的服务,但这是不可取的,因为它要求安装具有有关它可以升级的所有旧安装的信息(停止此特定服务可能涉及更多而不仅仅是简单地调用服务管理器来停止它)。
解决方案
我实施了问题中概述的潜在解决方案,调度 删除现有产品 就在之前 安装验证. 。我还没有看到任何问题,但在安装得到更多使用后我会再次发布。
更新
我们的安装已经使用这个有一段时间了,我没有注意到任何不良影响。
其他提示
它已经内置到 MSI / Windows Installer 中......唯一的问题是 .NET 安装程序类不使用 MSI“服务安装”功能。实际发生的情况是,MSI 正在尝试安装文件并使用刚刚复制的文件运行自定义命令(这就是 Visual Studio 放入 MSI 中的所有内容)。
要解决此问题,您可以使用 ORCA 编辑 MSI 并将以下行添加到 服务控制 桌子:
1 ServiceName 170 1 C__489628C5CC1144CB47F43E8BE7F3F31D
您可以从 FILES 表中查找组件 ID ...我刚刚选择了主 EXE 文件的组件 ID。170 是一个位图,告诉 Windows Installer 在安装和卸载时停止并删除服务。
这将为 .NET 安装程序添加服务扫清道路,并且您可以在通过自定义命令安装服务后使用 ServiceController 来启动服务。
一个潜在的问题是,如果用户在 InstallValidate 期间取消(例如由于没有足够的磁盘空间或文件正在使用)或在安装过程中,回滚行为是什么。理想的情况是应用程序状态与以前相同(例如之前的应用程序已安装)。您可能会在排序时放弃这一点,尽管回滚可能是您可以没有的功能。
我认为这将在不违反 MSDN 文档的情况下帮助您,并避免将来出现任何问题。设置条件“已安装或 PREVIOUSVERSIONSINSTALLED”,您也可以顺利升级,因为属性 PREVIOUSVERSIONSINSTALLED 是在 FindRelatedProducts 期间的 InstallValidate 操作之前设置的。我不知道为什么,但 MSDN 中没有记录 PREVIOUSVERSIONSINSTALLED 属性,但它确实存在并且对我来说非常有帮助。