以编程方式检测正在安装的 MSI 包

Programmatically detect MSI package being installed

我想知道包裹是否installed/upgraded。

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

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

谢谢

Major Upgrade: 如果您的MSI正在进行重大升级,那么之前版本的产品代码将被添加到属性 指定为最新包 Upgrade table 中的 ActionProperty。在 WiX 中,这个 属性 通常被称为 WIX_UPGRADE_DETECTED,但它可以被称为任何东西。

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

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

查找已安装产品:您可以轻松获取已安装产品的产品代码: The MSI API features a lot of methods and properties that can be used to determine pretty much whatever you want about an installed MSI. It can be accessed via COM, Win32, Managed code.

UPDATE: the script here shows how to identify related products by means of the MSI API RelatedProducts call. Towards bottom.


部分链接:

  • Run Wix Custom action only during uninstall and not during Major upgrade(对上述属性的更详细描述 - 不同的词和格式)
  • MSI 提示:通知用户何时进行重大升级 地点 (Flexera)
  • wix installer update process and confirmation dialog(VBScript 中的一个实现 - 所有的东西 - 在主要升级时向用户显示一个对话框。我不推荐这个,但这只是一个示例)。
  • check for windows installer mutex availability

因为我想检测什么是 Windows 安装程序安装但进程外,这是我到目前为止所做的:

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