如何在安装MSI时以编程方式检测成功或失败?

时间:2009-11-10 14:46:50

标签: windows-installer

我有一个安装多个MSI软件包的bootstrapper应用程序。但是,如果安装失败,Windows安装程序似乎不会返回任何错误代码。例如,如果我点击“取消”,则以下命令行测试不会打印“失败”:

msiexec /i myinstaller.msi || echo failed

鉴于缺少错误反馈,检测安装失败的最佳方法是什么?

<小时/> 如接受的答案所示,实际上返回了错误代码。出于某种原因,我的测试用例只能在从批处理文件执行时按预期工作,而不是直接在命令行输入。

4 个答案:

答案 0 :(得分:5)

  

自Windows Installer 1.0首次发布以来,msiexec.exe始终如此   在Windows子系统中运行。这意味着当它从中执行时   控制台或批处理脚本控件返回控制台或   脚本立即。如果你依赖于%ERRORLEVEL%变量   相应地设置它不会。

     

在这种情况下,我喜欢使用命令行中的start /wait或a   批处理脚本。这将创建进程并等待它退出,   并且流程的返回码被传递并返回   从start命令开始,相应地设置%ERRORLEVEL%。只是   在您通常传递给的命令行之前键入start /wait   msiexec.exe如下例所示:

     

start /wait msiexec.exe /i netfx.msi /l*v netfx.log

     

然后,将阻止批处理脚本,直到msiexec.exe完成。   以编程方式这与调用msiexec.exe没什么不同   CreateProcess并等待用信号通知的进程句柄   WaitForSingleObject没有超时。

来源:https://blogs.msdn.microsoft.com/heaths/2005/11/15/waiting-for-msiexec-exe-to-finish/

示例代码:

start /wait msiexec.exe /i netfx.msi /l*v netfx.log

if "%errorlevel%" == "0" goto OK
if "%errorlevel%" == "1013" goto err
if "%errorlevel%" == "1603" goto err
if not "%errorlevel%" == "0" goto err

:OK
GOTO END

:err
rem print message and return errorlevel so package errors
echo "Error: Msiexec failed with errorlevel = %errorlevel%"
exit /b %errorlevel%

:END

代码参考:https://www.computing.net/answers/windows-xp/batch-file-to-install-msi-and-check-errorlvl/178657.html

答案 1 :(得分:4)

实际上,msiexec 会返回错误代码,两个成功代码为0(成功)和3010(成功,需要重新启动)。也许cmd.exe在你的例子中做了一些不必要的魔术(比如在msiexec完成之前返回),但是当我通过VBScript的WScript.Shell Run(bWaitOnReturn = True)执行它时,我成功读取了msiexec错误代码。

尝试将以下内容放入test.vbs文件中,然后使用cscript test.vbs执行它:

Set WshShell = WScript.CreateObject("WScript.Shell")
MsgBox(WshShell.Run("msiexec /i myinstaller.msi", , true))

如果您点击取消,它应该弹出非零值。

答案 2 :(得分:2)

如果您点击取消,则不是错误,安装程序正在执行请求的操作,并且很可能将0返回到取消功能。

答案 3 :(得分:1)

msiexec在安装失败时return an error。要抓取用户取消,您可能需要使用MIF file