There are two problems:
Util.exe
is actually not called in the context of the cmd
instance you initiate, but I guess you want that; to resolve this, either escape the ampersand or quote the command line:
cmd /C MainApp.exe ^& Util.exe
or:
cmd /C "MainApp.exe & Util.exe"
Since you are trying to write and read a variable in the same command line/block, you need to enable and apply delayed expansion, which can be achieved by cmd /V
, like this:
cmd /V /C MainApp.exe ^& set /A ERR=!ErrorLevel! ^& Util.exe ^& exit !ERR!
or:
cmd /V /C "MainApp.exe & set /A ERR=!ErrorLevel! & Util.exe & exit !ERR!"
This works only given that MainApp.exe
also sets the ErrorLevel
, which is not always the same as the exit code. If it does not, you could try this (the ||
operator forces ErrorLevel
to equal the current exit code):
cmd /V /C MainApp.exe ^|^| rem/ ^& set /A ERR=!ErrorLevel! ^& Util.exe ^& exit !ERR!
or:
cmd /V /C "MainApp.exe || rem/ & set /A ERR=!ErrorLevel! & Util.exe & exit !ERR!"
In case Util.exe
does not need to be executed in case MainApp.exe
returns a non-zero exit code, do this (so the exit code of MainApp.exe
survives):
cmd /C MainApp.exe ^&^& Util.exe
or:
cmd /C "MainApp.exe && Util.exe"
If MainApp.exe
really does not set ErrorLevel
, you could try the following:
cmd /C MainApp.exe ^&^& Util.exe || rem/
or:
cmd /C "MainApp.exe && Util.exe || rem/"