MajorUpgrade 删除旧版本,但不安装新版本,除非 MSI 再次运行

Posted

技术标签:

【中文标题】MajorUpgrade 删除旧版本,但不安装新版本,除非 MSI 再次运行【英文标题】:MajorUpgrade removes old version, but doesn't install the new version unless the MSI is run a second time 【发布时间】:2017-09-18 19:38:20 【问题描述】:

我有两个相同的 MSI,但它们的 ProductId 和版本除外。我正在测试 MajorUpgrade 途径to make sure it's seamless for end users。

具有更高版本的 MSI 会关闭 Windows 服务并删除所有工件,但随后无法安装“新”二进制文件并出现 1603 错误。 实际上,它看起来像是在执行卸载,包括文件和注册表清理,但随后无法执行安装。

如果我再次运行更高版本的 MSI,安装工作正常:创建文件和目录,启动 Windows 服务,以及我设置为在安装完成后运行的可执行文件。

我生成了一个详细的日志(下面的 sn-ps),但解决问题似乎并不明显(文件没有复制到正确的位置)。

Wix 代码:

<Product Id="*"
    Name="product name"
    Language="1033"
    Version="1.2.0"
    Manufacturer="Company Name"
    UpgradeCode="stable-upgrade-guid">

<!-- snip -->

<Property Id="WixShellExecTarget" Value="[#TheProgram.exe]" />
    <CustomAction Id="LaunchApplication"
                  BinaryKey="WixCA"
                  DllEntry="WixShellExec"
                  Impersonate="yes" />

    <MajorUpgrade DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit." />

    <InstallExecuteSequence>
      <Custom Action="CheckForRunningProcesses_CA" After="InstallValidate" />
      <Custom Action="LaunchApplication" After="InstallFinalize"/>
    </InstallExecuteSequence>

我使用msiexec /i "product.msi" /l*v "upgrade.log" 生成了以下日志。这似乎是相关的位:

MSI (s) (70:B0) [14:30:58:905]: Note: 1: 2318 2:  
MSI (s) (70:B0) [14:30:58:905]: Note: 1: 1321 2: C:\Config.Msi\ 3: 5 
MSI (s) (70:B0) [14:30:58:905]: Note: 1: 2205 2:  3: Error 
MSI (s) (70:B0) [14:30:58:905]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 2911 
DEBUG: Error 2911:  Could not remove the folder C:\Config.Msi\.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2911. The arguments are: C:\Config.Msi\, , 
MSI (s) (70:B0) [14:30:58:908]: Note: 1: 2318 2:  
MSI (s) (70:B0) [14:30:58:908]: Calling SRSetRestorePoint API. dwRestorePtType: 0, dwEventType: 103, llSequenceNumber: 14, szDescription: "".
MSI (s) (70:B0) [14:30:58:909]: The call to SRSetRestorePoint API succeeded. Returned status: 0.
MSI (s) (70:B0) [14:30:58:909]: Unlocking Server
MSI (s) (70:B0) [14:30:58:911]: PROPERTY CHANGE: Deleting UpdateStarted property. Its current value is '1'.
Action ended 14:30:58: InstallFinalize. Return value 1.
MSI (s) (70:B0) [14:30:58:912]: Doing action: LaunchApplication
MSI (s) (70:B0) [14:30:58:912]: Note: 1: 2205 2:  3: ActionText 
Action 14:30:58: LaunchApplication. 
Action start 14:30:58: LaunchApplication.
MSI (s) (70:58) [14:30:58:915]: Invoking remote custom action. DLL: C:\WINDOWS\Installer\MSI12D1.tmp, Entrypoint: WixShellExec
WixShellExec:  Error 0x80070002: ShellExec failed with return code 2.
WixShellExec:  Error 0x80070002: failed to launch target
CustomAction LaunchApplication returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox)
Action ended 14:30:58: LaunchApplication. Return value 3.
Action ended 14:30:58: INSTALL. Return value 3.
我相信 ShellExec 返回码 2 的意思是“找不到文件”。 (确实,程序文件目录不存在。) 我不确定返回值为 3 的 LaunchApplication 是什么意思。我猜是“找不到文件”。

知道为什么 MajorUpgrade 会删除旧版本,但不安装新版本,但在后续运行时会安装?

【问题讨论】:

这不是完全重复。类似的症状,完全不同的日志文件。解决方法相同,但根本问题不同。 【参考方案1】:

我自然会在提出问题后立即发现答案。线索是in this *** question,不知怎的我没见过……

要解决此问题,您需要将您的 稍后执行 RemoveExistingProducts 操作。如果您使用的是 MajorUpgrade 元素然后Schedule='afterInstallExecute'Schedule='afterInstallFinalize' 应该可以解决问题。你需要成为 对组件规则更加小心。

MajorUpdate 的时间表更改为afterInstallExecute 是解决方法:

<MajorUpgrade
      DowngradeErrorMessage="A later version of [ProductName] is already installed. Setup will now exit."
      Schedule="afterInstallExecute" />

一点也不明显。

【讨论】:

以上是关于MajorUpgrade 删除旧版本,但不安装新版本,除非 MSI 再次运行的主要内容,如果未能解决你的问题,请参考以下文章

彻底删除旧版本mysql并安装新版本

安卓手机app如何旧版本覆盖新版本,不用卸载且不删数据?

Json文件更新但不读取旧文件?

发布新版本的应用程序会删除旧版本的文件吗?

go升级版本

go升级版本