To synchronously execute console applications or batch files in the current window, call them directly, do not use Start-Process
(or the System.Diagnostics.Process
API it is based on) - see this answer.
GitHub docs issue #6239 provides guidance on when use of Start-Process
is and isn't appropriate.
Direct execution not also allows you to directly capture an external program's output, it also reflects its process exit code in the automatic $LASTEXITCODE
variable afterwards.
Therefore:
cmd /c "`"$msbuild`" $buildCommand"
Note the need to use embedded double quotes around the executable path in the command line passed to cmd.exe
, given that it contains spaces.
Their effective absence is also was caused the problem in your Start-Process
call:
A long-standing bug in Start-Process
unfortunately requires use of embedded double-quoting around arguments that contain spaces, e.g. -ArgumentList '-foo', '"bar baz"'
.
It is therefore generally better to encode all arguments in a single string, e.g. -ArgumentList '-foo "bar baz"'
, because the situational need to use embedded double-quoting is then obvious.
See this answer for details.
In your specific case, you could make your Start-Process
call work as follows:
$startProcessArgs = "/c `"`"$msbuild`" $buildCommand`""
Note: That this works - despite the lack of escaping of the doubly nested "
chars. - is a testament to cmd.exe
's "quirks" when it comes to quoting.
Taking a step back:
msbuild.exe
, as any external program, can also be invoked directly from PowerShell. However, behind the scenes PowerShell transforms arguments such as /p:Platform="ASX Platform"
to "/p:Platform=ASX Platform"
, which msbuild.exe
may not understand.
There are several workarounds, with the call via cmd /c
being the conceptually cleanest.
Another one is use of --%
, the stop-parsing token, but it comes with severe limitations:
& "C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\msbuild.exe" C:\Git\Asd\build\XDA_2019.sln /m /t:Build /p:Configuration=Debug --% /p:Platform="ASX Platform"
Another one - limited to Windows PowerShell - is use to use embedded double quotes, which, however, relies on PowerShell's fundamentally broken handling of embedded double quotes in external-program arguments:
& "C:\Program Files\Microsoft Visual Studio\2022\Professional\MSBuild\Current\Bin\msbuild.exe" C:\Git\Asd\build\XDA_2019.sln /m /t:Build /p:Configuration=Debug '/p:Platform="ASX Platform"'
Another one - with all the disadvantages of Start-Process
use - is to use Start-Process
to call msbuild.exe
directly (not via cmd.exe
), which in your case would simplify your call to:
Start-Process -FilePath $msbuild -ArgumentList $buildCommand -PassThru -Wait -NoNewWindow