【问题标题】:Programmatically detect MSI package being installed以编程方式检测正在安装的 MSI 包
【发布时间】:2018-10-23 12:30:00
【问题描述】:

我想知道是否正在安装/升级软件包。

MSI 引擎设置了一个全局互斥体,但与产品无关。

我的一个想法是扫描正在运行的 msiexec 实例并检查命令行参数以确定 msi 文件并扫描其产品代码,但我想看看是否有更好的选择,虽然找不到任何合适的API。

谢谢

【问题讨论】:

  • 添加了一个指向使用 MSI API 的实际代码的链接。如果需要,我可以挖掘更多样本,但不想像往常那样“过度链接”。
  • 你想要什么类型的 sutable API?您可以拍摄快照并检查可执行文件名称 msiexec.exe。

标签: windows-installer programmatically


【解决方案1】:

重大升级:如果您的 MSI 正在执行重大升级,则先前版本的产品代码将添加到指定为 ActionProperty 的属性中 在最新包的Upgrade table 中。在 WiX 中,此属性通常按惯例称为 WIX_UPGRADE_DETECTED,但它可以称为任何名称。

换句话说,检查 WIX_UPGRADE_DETECTED 或等效属性是否有任何值可用于检测是否正在进行升级。

UPGRADINGPRODUCTCODE:在较旧的设置中 - 在主要升级期间被卸载的设置 - 内置 MSI 属性(与您声明的相反)UPGRADINGPRODUCTCODE 将设置为较新设置的产品代码。 换句话说,您可以在旧包的条件下使用此属性 (UPGRADINGPRODUCTCODE),但在较新的设置中不会设置它。这是一个很常见的混淆。请参阅此答案以更好地描述这种混乱:Run Wix Custom action only during uninstall and not during Major upgrade

查找已安装产品:您可以轻松获取已安装产品的产品代码:How can I find the product GUID of an installed MSI setup? The MSI API 具有许多可以使用的方法和属性几乎可以确定您想要的有关已安装 MSI 的任何信息。可以通过COM, Win32, Managed code访问。

更新the script here shows how to identify related products by means of the MSI API RelatedProducts call。走向底部。


一些链接

【讨论】:

  • 嗨 Stein,看到我自己的问题,注意到我忘了提及我想检测“OUTSIDE”msiexec/installer 进程。
【解决方案2】:

因为我想检测什么是 Windows Installer 安装但不在进程中,所以这是我到目前为止所做的:

  1. 扫描所有进程并分析C:\Windows\System32\msiexec.exeC:\Windows\SysWow64\msiexec.exe的所有实例
  2. 获取命令行参数并检查是否使用了/I
  3. 由于命令行中指定的msi文件可能不包含完整路径,并且进程的当前目录可能与进程启动时的目录不同,所以我使用以下方法扫描包。
  4. 使用VirtualQueryGetMappedFileName 扫描进程以查找所有内存映射文件
  5. 对于每个内存映射文件,尝试使用MsiOpenDatabase 打开它。 MsiOpenPackage 不起作用,因为安装程序正在使用该软件包。
  6. 运行 SQL 以从 Property 表中获取 ProductCodeUpgradeCode

【讨论】:

    猜你喜欢
    • 2011-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多