Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/128.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows installer 如何在安装MSI时以编程方式检测成功或失败?_Windows Installer - Fatal编程技术网

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

Windows installer 如何在安装MSI时以编程方式检测成功或失败?,windows-installer,Windows Installer,我有一个bootstrapper应用程序,它安装了几个MSI包。但是,如果安装失败,windows installer似乎不会返回任何错误代码。例如,如果我点击“取消”,以下命令行测试不会打印“失败”: 鉴于缺乏错误反馈,检测安装故障的最佳方法是什么 正如公认的答案所表明的,实际上返回了一个错误代码。出于某种原因,我的测试用例只有在从批处理文件执行时才能按预期工作,而不是直接在命令行中键入。实际上,msiexec确实返回错误代码,两个成功代码是0(成功)和3010(成功,需要重新启动)。在您的

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

鉴于缺乏错误反馈,检测安装故障的最佳方法是什么



正如公认的答案所表明的,实际上返回了一个错误代码。出于某种原因,我的测试用例只有在从批处理文件执行时才能按预期工作,而不是直接在命令行中键入。

实际上,
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