MSI安装失败,因为"已安装此产品的另一个版本"

Sha*_*n00 13 installer windows-installer msiexec

我们使用MSIEXEC使用以下命令行选项安装应用程序(MSI):

MsiExec.exe /x{code} /qn /liwearucmopvx+ C:\Log\UnInstall.tra
MsiExec.exe /iC:\Source\App.msi /qn TARGETDIR=C:\Install ALLUSERS=1 /liwearucmopvx+ %C:\Log\Install.tra
Run Code Online (Sandbox Code Playgroud)

大多数情况下这是有效的,但有时卸载失败(不确定为什么,查看错误).无论如何,当发生这种情况时,我在重新安装期间遇到以下错误:

Another version of this product is already installed.  Installation of this version cannot continue.  To configure or remove the existing version of this product, use Add/Remove Programs on the Control Panel
Run Code Online (Sandbox Code Playgroud)

有没有办法绕过这个?这意味着确保我们始终重新安装(如果存在,我们可以简单地自动将其吹走?)

sas*_*ont 8

查看升级表上MSDN文档,基本上您需要设置msidbUpgradeAttributesVersionMaxInclusive位.

您没有说明您用于构建安装程序的内容,如果您使用的是WiX 3.5或更高版本,则可以使用它MajorUpgrade/@AllowSameVersionUpgrades="yes"来为您处理此问题.

请注意,由于MSI忽略第四个产品版本字段,因此将此属性设置为yes还允许在前三个产品版本字段相同时降级.例如,产品版本1.0.0.1将"升级"1.0.0.2998,因为它们被视为相同版本(1.0.0).这可能会重新引入严重错误,因此最安全的选择是更改前三个版本字段并省略此属性以获取默认值no.

请注意,不必记住包代码(如果您使用自动生成的包代码与持续集成,真正的痛苦),以下VBScript将通过搜索已安装产品列表并查找包代码本身来删除包名称.

Option Explicit
Dim productName, productCode, installer 
productName = "My Application"

Set installer = Wscript.CreateObject("WindowsInstaller.Installer")

For Each productCode In installer.Products
    If InStr(1, LCase(installer.ProductInfo(productCode, "ProductName")), LCase(productName)) Then Exit For
Next

If Not IsEmpty(productCode) Then    
    Dim WshShell, oExec
    Set WshShell = CreateObject("WScript.Shell")
    Set oExec = WshShell.Exec("msiexec /x " & productCode & " /qb /l*v ""%temp%\UninstallApp.log"" ")
End If
Run Code Online (Sandbox Code Playgroud)


Ste*_*lly 0

如果卸载失败,产品仍将在系统上注册 - 根据失败发生的位置,卸载将回滚,使产品仍处于安装状态。

如果您尝试在现有安装之上重新安装具有相同产品代码但不同版本的产品,MSI 将正确地抱怨该产品仍然安装。如果要实现升级行为,则需要更改产品代码并将条目写入升级表,以便 MSI 可以区分新旧产品,并在新版本发布之前或之后使用“RemoveExistingProducts”操作删除旧产品放下。

如果您想了解卸载失败的原因,您需要查看日志,通常查找“返回值 3”,这是安装操作失败的签名。