Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Question
Monday, July 24, 2017 5:29 AM
Hi, I'm new with PowerShell. I'm trying to write a script related to MSBuild15.exe.
I'm running PowerShell on a 64-bit Windows 10 machine that has VS17 installed.
When using "x64 Native Tools command prompt for VS 2017" I could have just type msbuild to run MSBuild15.
However, when working with PowerShell, I have to type the full path.
$msbuild15EXE = 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe'
& $msbuild15EXE MySolution.sln /m /t:rebuild
...
Build succeeded.
0 Warning(s)
0 Error(s)... orBuild FAILED.
"PROJECT_DIR\MySolution.sln" (rebuild target) (1) ->
"PROJECT_DIR\MySolution\MySolution.vcxproj" (Rebuild target) (3) ->
(Link target) -> ...main.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: ...1 Warning(s)
2 Error(s)
These are my questions.
- I'm not sure what error code is returned from MSBuild15 when an LNK2019 error is created.
If the build is successful, the MSBuild returns 0, doesn't it?
Anyways, after the MSBuild returns something, I want to store it in a variable to run a conditional script.
For instance,
$errCode = RETURN_VALUE_FROM_MSBUILD15
# If the return code is 0, run VSTest.console.exe
If ($FileExists -eq 0){
# ...
}
Else{
# exit PowerShell with the error code
# for example, if the error code is 1
# run "exit 1"
}
Is this possible? If so, how should I configure the script to get the exit code of MSBuild15?
1) The variables are quite confusing to configure.
$msbuild15EXE = 'C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe'
$sol = 'C:\Users\USER0\Desktop\VCProj\MySolution.sln'
$opt = '/m /t:rebuild'
& $msbuild15EXE $sol $opt
MSBUILD : error MSB1001: Unknown switch.
Switch: /m /t:rebuild
# Or
$myCMD = "& $msbuild15EXE $sol $opt"
Invoke-Expression $myCMD
x86 : The term 'x86' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path
was included, verify that the path is correct and try again.
At line:1 char:21
+ & C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBui ...
+ ~~~
+ CategoryInfo : ObjectNotFound: (x86:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
I wanted to create variables that store the solution name and options for building them.
My methods returned errors.
How can I configure options and solution names as variables to build them?
-Best Regards
All replies (9)
Monday, July 24, 2017 5:41 PM ✅Answered
I usually end my scripts with something like:
if (-not $?) { exit 1 }
Then if I run it with
powershell -file ./scriptname.ps1
Powershell will return a errorlevel of 1 to whatever executed it (if the last command had the error).
Monday, July 24, 2017 5:44 PM ✅Answered
$? does not catch error for system utility programs.
Just exit after the build with: "exit $LASTEXITTCODE"
Add this line after the build:
Write-Host "EXIT CODE = $LASTTEXITCODE"
\(ツ)_/
Monday, July 24, 2017 9:13 AM
One way to control the execution of an external command or executable is to use the cmdlet Start-Process. Maybe like this:
$Result = (Start-Process -FilePath 'Executable' -ArgumentList 'Options for the executable' -Wait -NoNewWindow -PassThru).ExitCode
Now you have the exitcode in the variable $Result.
Grüße - Best regards
PS:> (79,108,97,102|%{[char]$_})-join''
Monday, July 24, 2017 9:20 AM
The return code is in $LASTEXITCODE. It is not returned from the execution. The execution returns text messages output from the build and most are returned on the error channel and not directly to the console channel. To get the results review the build log.
How to use build in a script or in a batch is an issue you should post in the VS forum. It is not a scripting issue.
\(ツ)_/
Monday, July 24, 2017 7:38 PM
Hmm. I have this simple C# program:
using System;
class Program {
static void Main() {
Environment.ExitCode = 1;
}
}
I compile it as a windows exe with (in cmd.exe)(/t:exe would make it command line):
set PATH=%PATH%;C:\Windows\Microsoft.NET\Framework\v4.0.30319
csc /t:winexe file.cs
In cmd.exe, I can run it with
start /wait file.exe
and it will set the %errorlevel% to 1. But it doesn't seem to change $? or $LASTEXITCODE in powershell:
start -wait .\file.exe
EDIT:
Oh I see, you have to add -passthru, then $LASTEXITCODE gets set to 1:
start -wait .\file.exe -passthru
A "command line" exe would set both $? and $LASTEXITCODE.
Monday, July 24, 2017 7:43 PM
$? is NOT set by external programs. $LASTEXITCODE is the variable the returns the exitcode of the last utility to run. It is the equivalent of %errorlevel%.
PS D:\scripts> cmd /c exit
PS D:\scripts> $lastexitcode
0
PS D:\scripts>
PS D:\scripts> cmd /c "dir x: && exit"
The system cannot find the path specified.
PS D:\scripts> $lastexitcode
1
\(ツ)_/
Monday, July 24, 2017 8:01 PM
In your own example, $? gets set to $false.
Monday, July 24, 2017 8:18 PM
In your own example, $? gets set to $false.
$? gets set to false if the exit code is not zero but it does not tell you what the exit code is. MSbuild returns ddifferent exit codes for different issues.
if($lastexitcode){
Write-Host "EXITTCODE = $lastexitcode"
}else{
Write-Host 'No Error reported'
}
$? is the old P{S 1.0 method of testing for errors and it is not generally used anymore. $LASTEXITCODE and Try/Catch have superseded it.
\(ツ)_/
Tuesday, July 25, 2017 8:03 AM
Thanks, jrv!
I received 0 after the MSBuild15 build successfully.
I will use your tip. Thanks!
-Best Regards