Wix FindRelatedProducts 找到了一个未安装的产品

Wix FindRelatedProducts has found a product which is not installed

在机器上测试了我的许多 install/uninstall 产品后,我遇到了一个没有安装我的产品的情况,至少我在控制面板中看不到它,但是当我尝试再次安装它,Wix 正在尝试更新未安装的产品。

我用日志执行了 msi,然后我发现 FindRelatedProducts 找到了一个 GUID 并填充了 WIX 属性 WIX_UPGRADE_DETECTED.

部分日志:

FindRelatedProducts: Found application: {MY-GUID}
MSI (c) (24:8C) [07:21:36:885]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{MY-GUID}'.

当我使用 WIX_UPGRADE_DETECTED 到 select 并显示对话框(安装或升级)时,显示的是升级对话框,但未安装任何产品。

如果我在另一台机器上测试,做同样的场景,FindRelatedProducts 没有找到任何产品,这是正确的情况。

我怀疑 windows 注册表 (regedit) 中的某些条目未被清理。 你知道 Wix 是如何检测 FindRelatedProducts 的吗?或者为什么 Wix 在未安装任何产品的情况下填充 WIX_UPGRADE_DETECTED

谢谢!

Windows 安装程序在注册表中进行了注册。它提供了一个 API 来检查该注册。在这种情况下,您需要 ::MsiEnumRelatedProducts()。它将通过 UpgradeCode.

为您提供所有相关产品

然后您可以通过以下方式卸载这些产品:

msiexec /x {PRODUCT-CODE-GUID}

您应该会发现 {PRODUCT-CODE-GUID} 与您编辑为 {MY-GUID} 的内容相同。

注意:这与 WiX 工具集无关。是 100% Windows 安装程序行为(又名:MSI)。

FindRelatedProducts 由 Windows 安装程序而非 WiX 执行。您断言行为不正确肯定是不正确的。你有一台脏机器,MSI 有工件表明它已安装。你的另一台机器是干净的,但不是。

Short Answer: The answer below is probably too elaborate, just do an uninstall of what your upgrade setup finds and then try to install again.

From a command prompt (Windows Key + Tap R + Type: cmd.exe + Enter) run the following command:

msiexec.exe /x {GUID-FROM-LOG-FILE}

The GUID is (most likely) the one from your log file: WIX_UPGRADE_DETECTED. Then try installing again.

Failing Uninstall: If the uninstall fails, try running this Microsoft FixIt tool. Sometimes it can sort out setups that don't uninstall properly. Alternative, under the hood fix (not recommended).


UpgradeTable:我要做的第一件事是验证 UpgradeTable 中的内容 在显示问题的已编译 MSI 文件中。那里的升级代码是否与您设置的升级代码匹配? (UpgradeCode entryProperty Table)。

UpgradeTable 的内容决定了哪些现有安装(如果有)被检测为与您的新安装相关。如果你在这里配置了奇怪的东西,你甚至可能最终会卸载被错误检测为与你的产品相关的竞争产品——我不会那样做:-)。文书工作太多。


卸载: 现在,如何解决安装问题?您需要获取 ProductCode GUID。有许多方法可以获取此信息。 它应该是您在 WIX_UPGRADE_DETECTED 的 MSI 日志中看到的产品 G​​UID,因此请先尝试:

msiexec.exe /x {GUID}

这里是一般意义上卸载 MSI 设置的答案(各种不同的选项 - 快速阅读?):Uninstalling an MSI file from the command line without using msiexec


ProductCode (GUID):Rob 已经提到了正确的 MSI API 来列出已安装的产品,我只会补充一点,我这里有这个答案可以提供帮助: 它列出了几个选项来查看你的盒子上安装了什么。

VBScript / COM Automation:我将直接内联上面第一个 link 中的 VBScript 选项(有几个linked 答案中列出的选项):

' Retrieve all ProductCodes (with ProductName and ProductVersion)
Set fso = CreateObject("Scripting.FileSystemObject")
Set output = fso.CreateTextFile("msiinfo.csv", True, True)
Set installer = CreateObject("WindowsInstaller.Installer")

On Error Resume Next ' we ignore all errors

For Each product In installer.ProductsEx("", "", 7)
   productcode = product.ProductCode
   name = product.InstallProperty("ProductName")
   version=product.InstallProperty("VersionString")
   output.writeline (productcode & ", " & name & ", " & version)
Next

output.Close

PowerShell:同时加入 PowerShell 选项。在某些情况下,这会触发意外的自我修复。

get-wmiobject Win32_Product | Format-Table IdentifyingNumber, Name, LocalPackage -AutoSize

我能够确定导致我提到的错误的机器上留下的注册表项是什么。

它们位于以下位置:

 - HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\UpgradeCodes\{OTHER-GUID}
 - HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Installer\Products\{OTHER-GUID}

请注意,{OTHER-GUID} 不是我的产品代码,而是生成的代码,我的产品代码是这些注册表项中存在的值之一。

只要删除它们,我的安装程序就会重新运行。

谢谢@stein-Åsmul 这个命令:get-wmiobject Win32_Product 很有帮助。