How do I programmatically detect success or failur

2019-05-07 03:25发布

I have a bootstrapper application which installs several MSI packages. However, it seems that windows installer does not return any error code if the installation fails. For example, the following command line test does not print "failed" if I hit "cancel":

msiexec /i myinstaller.msi || echo failed

Given the lack of error feedback, what is the best way to detect an installation failure?


As the accepted answer suggests, an error code is actually returned. For some reason my test case only works as expected when executed from a batch file, rather than typed directly at a command line.

4条回答
手持菜刀,她持情操
2楼-- · 2019-05-07 04:02

Since Windows Installer 1.0 was first released, msiexec.exe has always run in the Windows subsystem. That means that when it is executed from the console or by a batch script control returns to the console or script immediately. If you depend upon the %ERRORLEVEL% variable being set accordingly it won’t be.

In this scenario I like to use start /wait from the command line or a batch script. This will create the process and wait for it to exit, and the return code from the process is passed through and returned from the start command such that %ERRORLEVEL% is set accordingly. Just type start /wait before the command line you’d normally pass to msiexec.exe like in the following example:

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

A batch script would be blocked, then, until msiexec.exe finishes. Programmatically this is no different than invoking msiexec.exe with CreateProcess and waiting for the process handle to be signaled with WaitForSingleObject with no timeout.

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

Sample code:

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

Code reference: https://www.computing.net/answers/windows-xp/batch-file-to-install-msi-and-check-errorlvl/178657.html

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-05-07 04:07

If you hit cancel it isn't an error, the installer is performing the requested action, and is most likely returning 0 to the cancel function.

查看更多
来,给爷笑一个
4楼-- · 2019-05-07 04:19

Actually, msiexec does return error codes, the two success codes being 0 (success) and 3010 (success, reboot required). Maybe cmd.exe does some unwanted magic in your example (like returning before msiexec has finished), but I successfully read msiexec error codes when executing it via VBScript's WScript.Shell Run (with bWaitOnReturn = True).

Try throwing the following in a test.vbs file and then executing it with cscript test.vbs:

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

It should pop up with a non-zero value if you hit Cancel.

查看更多
Evening l夕情丶
5楼-- · 2019-05-07 04:19

msiexec does return an error on installation failure. To catch a user cancel, you might need to use a MIF file.

查看更多
登录 后发表回答