6

如果我在安静模式下使用 MSIExec 启动安装程序,我可以通过检查退出代码是否为 3010 来检测是否需要重新启动才能完成安装。但我希望能够以可编程形式做的是测试是否在我启动实际安装程序之前,MSI 的安装需要重新启动才能完成。

我查看了 MSI API:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa369426(v=vs.85).aspx

我确实认为我可以:

  1. 调用 MsiOpenPackage 让安装程序准备好运行
  2. 使用以下命令调用 MsiDoAction:CostInitialize、FileCost、CostFinalize、InstallValidate
  3. 从 FilesInUse 表中读取记录(MSDN 上的以下文档建议此表是在运行 CostFinalize/InstallValidate 后创建的:

http://msdn.microsoft.com/en-us/library/aa369546(VS.85).aspx

但是,当我在安装过程中查询它时,该表实际上并不存在。是否有其他方法可以检查是否需要重新启动?

4

3 回答 3

4

Gareth,理论上您不需要执行实际安装,您应该只执行操作,直到 InstallValidate(包含),因为此时会出现 Files In Use 消息。但是,当使用外部 UI 处理程序执行安装时,Windows Installer 的行为可能会有所不同,因此应该进行测试。

于 2012-05-29T07:22:45.143 回答
2

最终仅在安装过程中做出决定。如您所知,它取决于诸如 DLL 被同时运行的应用程序锁定的情况,因此它非常不稳定。

无法保证在实际安装完成后您不会收到退出代码 3010。

也就是说,退出代码与正在使用的文件没有那么紧密的联系。它还可能表示无法停止服务,或者可能是其他一些暂时或永久的情况。在您尝试之前,您无法了解是否可以停止服务。

于 2012-05-28T21:45:06.003 回答
1

Jirka 关于需要重启的波动性是正确的——在安装过程中可能会发生各种事情。

但是,我认为我已经接近了我希望能够用不同的方法做的事情:

  1. 为 INSTALLLOGMODE_RMFILESINUSE 注册一个外部 UI 处理程序
  2. 捕获 INSTALLMESSAGE_RMFILESINUSE 消息
  3. 如果我捕获任何 INSTALLMESSAGE_RMFILESINUSE 消息,请在任何文件复制继续之前返回 -1 并退出安装

通过这种方式,我可以尝试在后台静默安装软件,但如果由于任何原因看起来我无法完成安装,我可以阻止。如果我最终处于用户在开始复制后锁定文件的状态,我想我也可以使用 MsiBeginTransaction 和 MsiEndTransaction 函数进行回滚。

于 2012-05-28T22:21:38.970 回答