I'm writing a batch file that runs a command via git-cmd.exe but it doesn't run the command(s) after it.
I've tried to use CALL, START /WAIT, and START /B /WAIT. All have the same behavior. Maybe there is a parameter should be sent to git-cmd.exe to execute the command and exit but I didn't find any guide explaining how to use git-cmd.exe.
This is a sample batch file:
#ECHO OFF
SET "PATH=C:\Ruby26-x64\bin;C:\Program Files\nodejs;%PATH%"
SET "CurrentDirectory=%CD%"
CD /D "%UserProfile%\AppData\Local\GitHub\PortableGit_*\"
SET "GitDirectory=%CD%"
CD /D "%CurrentDirectory%"
"%GitDirectory%/git-cmd.exe" CALL rake build
PAUSE
The command passed to git-cmd.exe is executed but the PAUSE command doesn't execute until I type EXIT command manually in the 'Command Prompt' window.
I've also tried a simple DIR command instead of rake build but the same issue still occurs:
"%GitDirectory%/git-cmd.exe" DIR
PAUSE
Thanks to the suggestions, the issue was resolved by passing EXIT command to git-cmd.exe as follows:
#ECHO OFF
SET "PATH=C:\Ruby26-x64\bin;C:\Program Files\nodejs;%PATH%"
SET "CurrentDirectory=%CD%"
CD /D "%UserProfile%\AppData\Local\GitHub\PortableGit_*\"
SET "GitDirectory=%CD%"
CD /D "%CurrentDirectory%"
"%GitDirectory%/git-cmd.exe" "CALL rake build & EXIT"
PAUSE
There was a useful conversation between me and someone else (I think his name was mony) but it was deleted, don't know why?!
He sent me this link with the difference between & and && between commands:
https://stackoverflow.com/a/25344009/9586127
The & before the EXIT command in order to execute both commands independent on result of the first one. If && is used, the EXIT command will be executed only if the first command succeeded (exit code 0).
In addition, he told me a way to replace the lines 3:6 by one line to be:
FOR /D %%I IN ("%LocalAppData%\GitHub\PortableGit_*") DO SET "GitDirectory=%%I"
I googled for a solution for how to pause and executable is an error is encountered. The most promising thing I found was this:
#echo off
"C:\Users\ryans\dist\AS_to_GBQ.exe" %1
if %errorlevel% neq 0 exit /b %errorlevel%
I put that in my Command Prompt, and run it. Now, the exe opens, runs, throws an error, and the exe shuts down with no indication of what actually happened. How can I see the details of the error, or somehow troubleshoot this issue? I'm on Windows 10. I can run this as a batch file, or through PowerShell, if that helps.
When I run this command from the command line, I get the error RC 1107:
d:\dev\projects\res\compiler\rc.exe RC /r /fo d:\dev\projects\res\output\manifest.res d:\dev\projects\res\compiler\manifest.rc
All mentioned paths exists.
I am not in the drive and path when I call this command, but I would tend to think that it should not matter since I am giving the paths explicitely.
Thank you for the help.
Solution:
ChDrive "d:\"
ChDir "d:\dev\projects\res\compiler"
Then I called
"RC /r /fo ..."
from the command line.
I guess that I mixed up RC and rc.exe somehow. If anybody can give a clean explanation, I will of course accept his / her reply as the answer.
We have a project in Visual Studio 2010 that runs a batch file in the post-build event. That batch calls to signtool.exe from Microsoft SDK to sign and timestamp the binary.
Timestamp servers (we use http://timestamp.verisign.com/scripts/timstamp.dll), however, tend to be unreliable for some reason, failing sometimes. This caused build to fail.
We implemented a more advanced batch script then (based on this code), splitting signing and timestamping, and allowing to retry the timestamp operation, if it failed.
Here is a simplified version of the batch script (signfile.bat):
#echo off
REM sign the file...
signtool.exe /f Authenticode.pfx /p PASS %1
if %errorlevel% neq 0 exit /b %errorlevel%
set timestamp_server=http://timestamp.verisign.com/scripts/timstamp.dll
for /L %%a in (1,1,10) do (
REM try to timestamp the file...
signtool.exe timestamp /t %timestamp_server% %1
if errorlevel 0 if not errorlevel 1 GOTO succeeded
REM wait 2 seconds...
ping -n 2 127.0.0.1 > nul
)
REM return an error code...
echo signfile.bat exit code is 1.
exit /b 1
:succeeded
REM return a successful code...
echo signfile.bat exit code is 0.
exit /b 0
And the post-build event code would look like:
signfile.bat "$(OutDir)$(TargetName)$(TargetExt)"
So, if the timestamping fails, it retries 10 times with 2-seconds intervals.
But, what we observed was, if the timestamping went fine from the first attempt, everything was OK. However, if the first attempt failed, then the whole post-build event failed with code -1, even though the timestamping succeeded on the next try.
1>------ Build started: Project: myproject, Configuration: NonOptimized x64 ------
1> Done Adding Additional Store
1> Successfully signed: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>
1>EXEC : SignTool error : The specified timestamp server either could not be reached
1> or returned an invalid response.
1> This may happen if you specify an RFC 3161 timestamp URL but used
1> the /t option or you specified a legacy Authenticode timestamp URL
1> but used the /tr option.
1>EXEC : SignTool error : An error occurred while attempting to timestamp: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>
1>
1> Number of errors: 1
1>
1> Successfully timestamped: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>
1> signfile.bat exit code is 0.
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: The command "signfile.bat "E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll"
1>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(113,5): error MSB3073: :VCEnd" exited with code -1.
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========
So, as you can see, even though the error code returned from signfile.bat is 0, Visual Studio thinks it is -1 and fails the event.
All attempts to clear the error flag, like adding ver>nul here and there, or adding exit 0 in the end (certainly with adding "call" before signfile.bat) didn't help since it seemed like Visual Studio checked not just for errorlevel but also for something else. In fact, the batch as well as signfile.bat only return 0 or 1 in case of error, but not -1. And if signtool.exe returns an error once, it seems like there is no way to convince Visual Studio not to fail the post-build event.
After spending much time experimenting and searching, found an article, mentioned here in a comment. It looks like Visual Studio scans the output, searching for some special keywords. Signtool.exe outputs among the other EXEC : SignTool error : An error occurred, which seems like enough to alert Visual Studio that there was an error.
So, the solution proposed was to redirect output and error streams to nul as 2>nul 1>nul. Errorlevel will still be set, so you will be able to figure out if error occured. But you may have to print some extra messages to see the status:
REM try to timestamp the file...
signtool.exe timestamp /t %timestamp_server% %1 2>nul 1>nul
if errorlevel 0 if not errorlevel 1 (
echo Successfully timestamped: %1
GOTO succeeded
)
echo Timestamping failed for %1
Now Visual Studio is happy:
1>------ Build started: Project: myproject, Configuration: NonOptimized x64 ------
1> Done Adding Additional Store
1> Successfully signed: E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll
1>
1> Timestamping failed for "E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll"
1> Successfully timestamped: "E:\tfs\MySolution\bin\x64\NonOptimized\myproject.dll"
1> signfile.bat exit code is 0.
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
In fact, just adding 2>nul would be enough to fix it. Error stream will still be printed: Number of errors: 1, but it does not cause a problem.
I experienced a very similar problem, but with the added difficulty that rather than calling SignTool directly, our post-build step calls a PowerShell script which itself calls SignTool. I set up some retry logic in the PowerShell script (to try various timestamp servers, with delays), but found that if the first attempt failed then the whole build would fail, even though the error was being caught and handled properly and a subsequent signing attempt was succeeding.
I appreciate this isn't exactly what the original question is asking, but I wasted hours and hours on this before eventually working out a solution (having stumbled upon this Q&A - thank you!), so I'm posting this info in the hope that it will help others.
From PowerShell, the standard call to SignTool would be something like this:
$output = & $signToolPath sign `
/n $companyName `
/d $productName `
/du $productWebsite `
/t $timestampServer `
/sha1 $shaHash `
$filePath
If SignTool returns an error code, this will immediately fail the build (as shown in the TeamCity screenshot), which is not desirable if the script is capable of automatically retrying:
To prevent the build failing, the PowerShell error stream can be suppressed (similarly to the solution in the accepted answer) with the PowerShell redirect statement 2>&1 as follows:
$output = & $signToolPath sign `
<switches and args as above>
$filePath 2>&1
However, this means you can't see the error output when SignTool returns an error code, which is obviously unhelpful. You can address this by writing the output to the host like this:
$output = & $signToolPath sign `
<switches and args as above>
$filePath 2>&1
$output | Write-Host
but then Visual Studio / MSBuild will resume trying to be "clever" and fail the build again!
The only solution I have found which allows SignTool error messages to be displayed without failing the build is both to redirect the error stream and to garble the error output before writing to the host, something like this:
$output = & $signToolPath sign `
<switches and args as above>
$filePath 2>&1
$output -split "([a-z0-9])" -join " " | Write-Host
The error message is then human-readable but doesn't fail the build, as shown here:
Of course, if all the retry attempts fail then you need to return an appropriate non-zero exit code from the PowerShell script so that the build does fail.
Thanks again for the original Q&A, and I hope this extra info on PowerShell helps someone else.
(PS: one of the links in the accepted answer is broken, but the referenced article is archived here: http://web.archive.org/web/20180729111947/http://blog.robertromito.com/2010/08/ignore-error-from-visual-studio-post.html )
I have a test project that builds fine. I am trying to run the tests using mstest. Here is the command I am executing:
Command:
echo mstest.exe /testcontainer:SecurityLogging.Tests\Logging.Tests.dll /resultsfile:%TEST_LOG_ROOT%\Execute_%TestListNode%_1.trx /detail:Owner /detail:Description /nologo /testsettings:Logging.Tests\Local.testsettings /category:"^!E2E&^!Stress&^!Perf"
My tests FAILED. If I then check the error level. It is still 0. I did:
if %errorlevel%==0 (
continue;
)
and it always continues.
I am using Visual Studio 2010. I started digging and I found this:
http://www.mail-archive.com/ccnet-user#googlegroups.com/msg03027.html
Thanks
MSTest is not failing. It executes the tests fine. Your tests are failing and their errors are handled by MStest. So, I think you will not get any %errorlevel%.
I've just confirmed that mstest.exe for Visual Studio 2010 does in fact exit with errorlevel 1 when it runs tests and some of them fail. When all the tests pass, it returns errorlevel 0.
You can verify this with the following lines in your batch file after running mstest:
echo %errorlevel%
pause
If your batch file is being called by another batch file, and you want to pass the errorlevel back, then you can use if not %errorlevel% == 0 exit 1 to shortcut your batch file.
Otherwise, as #Magoo indicates, you may have an unnecessary echo at the front of your call to mstest.exe.