是否可以从msi获取现有安装的详细清单?

时间:2016-04-20 15:44:20

标签: wix windows-installer msiexec

安装后是否可以从MSI访问文件和注册表清单以及文件校验和?或者,有没有办法让msi验证现有安装并生成详细日志?我问,因为我需要创建一个安装资格报告,该报告在安装后或按需生成。如果我可以直接从msi中读取产品的清单,那么创建生成该报告的程序就很容易了。否则,我必须以某种方式创建一个详细的清单,并将其包含在已安装的文件中供以后参考。有什么建议? Wix或其他工具是否有内置机制用于此类事情?感谢。

1 个答案:

答案 0 :(得分:0)

了解这个目标或潜在问题会很有用。有人认为安装可能在某种意义上没有起作用,因此可能会丢失文件或注册表项并需要验证。但MSI安装不会那样工作。它要么完全成功并安装所有内容,要么失败并回滚,将系统恢复到以前的状态(因为它是一个事务)。换句话说,Windows Installer安装正确文件的验证和鉴定报告基本上是开始测试Windows工作的业务,并且大多数人将其留给Microsoft :)。

如果(例如)涉及共享文件(无论是您的,Microsoft还是第三方),还存在一些实际问题。如果已在系统上的共享位置安装版本6.0的SomeFile.Dll,并且您的设置包含安装到同一位置的SomeFile.Dll版本5.0,那么您的验证工具可能会报告失败 - 它没有安装版本5.0!同样,如果您尝试覆盖已更新的数据文件,则该文件将不会被替换,并且可以使用哪种验证来检查"是否正确"文件已安装或未安装?因此,在这些情况下,实际安装的任何可能的列表都可能注定要失败。它还不清楚如何验证(例如)服务是否已正确安装。如果您使用(例如)ServiceInstall来安装服务,那么资格是否应该验证服务是否已安装且Windows是否按预期执行了操作?

如果MSI中的每个文件都标记为keypath yes,那么清点系统的一种方法是使用MsiEnumComponents(),枚举系统上每个已安装的MSI组件。对于每个组件ID,MsiEnumClients()将返回共享组件的ProductCodes列表,您的ProductCode应该是其中之一。有些将是注册表项。我相信有一些系统管理工具可以完成这种系统库存。

更有针对性的方法是使用Windows Installer SQL API枚举MSI的Component表中的所有内容,并为每个组件执行MsiGetComponentPath(ProductCode,Component guid ....)以查看每个组件已安装并检查它(并获取其版本?)。除了我已经提到的共享问题,如果用户可以选择要安装的功能,那么MSI中的所有内容都不会安装,因此验证的意思意味着您需要知道安装了哪些功能,并相应地进行过滤,但是那个测试Windows做了它应该做的事情。

如果您必须根据MSI文件中的内容验证已安装的文件,那么您需要浏览MSI的Component表,并且:

  1. 对于版本化文件,您可以使用组件名称链接到MSI的File表,因为它包含版本。 MsiGetComponentPath()告诉您可以调用MsiGetFileVersion()的已安装文件的路径,并与MSI中的版本进行比较。

  2. 对于散列数据文件,您可以使用组件名称查看MSI中的MsiFileHash表。如果有哈希,请取出四个字段并与已安装文件的哈希值进行比较(在MsiGetComponentPath上)。

  3. 换句话说,您不需要原始文件,因为数据是在构建时的MSI文件中。