Windows installer 如何在安装MSI时以编程方式检测成功或失败?
我有一个bootstrapper应用程序,它安装了几个MSI包。但是,如果安装失败,windows installer似乎不会返回任何错误代码。例如,如果我点击“取消”,以下命令行测试不会打印“失败”: 鉴于缺乏错误反馈,检测安装故障的最佳方法是什么Windows installer 如何在安装MSI时以编程方式检测成功或失败?,windows-installer,Windows Installer,我有一个bootstrapper应用程序,它安装了几个MSI包。但是,如果安装失败,windows installer似乎不会返回任何错误代码。例如,如果我点击“取消”,以下命令行测试不会打印“失败”: 鉴于缺乏错误反馈,检测安装故障的最佳方法是什么 正如公认的答案所表明的,实际上返回了一个错误代码。出于某种原因,我的测试用例只有在从批处理文件执行时才能按预期工作,而不是直接在命令行中键入。实际上,msiexec确实返回错误代码,两个成功代码是0(成功)和3010(成功,需要重新启动)。在您的
正如公认的答案所表明的,实际上返回了一个错误代码。出于某种原因,我的测试用例只有在从批处理文件执行时才能按预期工作,而不是直接在命令行中键入。实际上,
msiexec
确实返回错误代码,两个成功代码是0(成功)和3010(成功,需要重新启动)。在您的示例中,cmd.exe可能会执行一些不需要的魔法(比如在msiexec完成之前返回),但在通过VBScript执行它时(bWaitOnReturn=True),我成功地读取了msiexec错误代码
尝试在test.vbs文件中抛出以下内容,然后使用cscript test.vbs
执行它:
Set WshShell = WScript.CreateObject("WScript.Shell")
MsgBox(WshShell.Run("msiexec /i myinstaller.msi", , true))
如果单击“取消”,它将弹出一个非零值。msiexec在安装失败时执行此操作。要捕获用户取消,您可能需要使用 如果您点击cancel,则这不是错误,安装程序正在执行请求的操作,并且很可能会将0返回到cancel函数 自Windows Installer 1.0首次发布以来,msiexec.exe始终 在Windows子系统中运行。这意味着当它从 控制台或批处理脚本控件返回到控制台或 立即编写脚本。如果您依赖所使用的
%ERRORLEVEL%
变量
相应地设置它将不会被删除
在这种情况下,我喜欢从命令行或
批处理脚本。这将创建进程并等待它退出,
进程的返回代码被传递并返回
从start命令开始,相应地设置%ERRORLEVEL%
。只是
在通常传递到的命令行之前键入start/wait
msiexec.exe与以下示例类似:
start/wait msiexec.exe/i netfx.msi/l*v netfx.log
批处理脚本将被阻止,直到msiexec.exe完成。
以编程方式,这与使用
CreateProcess,并等待向进程句柄发送信号
没有超时的WaitForSingleObject
资料来源:
示例代码:
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
代码参考:+1用于解释测试用例不工作的原因。您的测试用例和批处理文件都需要使用
调用msiexec | | echo失败
。(necro、fwiw等)
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