views:

397

answers:

4

I have a batch file that's being run in a Visual Studio custom build step to copy files into an install directory. I want it to error out properly when the copy fails. The problems with the options I have are:

  • exit 1
    This works within the build sequence fine, but sometimes I want to use the batch file from the command line or from within another batch, and in these cases the exit causes the caller to exit as well.

  • exit /b 1
    This works nicely from the command line or from another batch file, but Visual Studio doesn't recognize that the return code wasn't 0 (i.e. it reports the project having "0 error(s)").

I came across a link that provides me with a solution: http://www.nabble.com/Re:-bjam-and-Windows-p17457249.html

Essentially it says I have to echo an error message before doing the exit /b. For instance,

echo MyProj : error : could not copy files.

Does anyone know exactly what message format triggers Visual Studio to recognize an error?

I've tried tweaking this and some work and some don't. Seems it has to match something like

.*\: .*error.*\:

Is this documented anywhere?

Thanks.

This is with Visual Studio 2008 SP1 on Windows XP Pro SP3 (in case cmd.exe has differing behaviour between Windows versions).

+1  A: 

Are you quite sure you're testing this correctly? I've just tried this batch file:

echo bla
exit /b 1

with VS2008, as a pre-build step and got this:

1>------ Build started: Project: XXXX, Configuration: Debug Win32 ------
1>Performing Pre-Build Event...
1>bla
1>Project : error PRJ0002 : Error result 1 returned from 'C:\Windows\system32\cmd.exe'.
1>Build log was saved at "file://c:\XXXXX\BuildLog.htm"
1>XXXXX - 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I've also tried this with a custom build step for a file with the same exact result.
It should be noted that I am used VS2008-SP1 so that might be the difference.

shoosh
Interesting. This is currently a custom build step on the file. I tried it as a build event and got the same result. I even tried changing the script to be exactly what you have.But yes, I'm quite sure it doesn't work the same on my machine. Simply modifying the "echo" line changes the result.
Owen
+1  A: 

Generally, the return value of a batch file is the return value of the last command executed from within the batch file.

Exit should work, but if it doesn't, for whatever reason, you could always use a helper program to set your return value.

Back in the DOS days, you could use ECHO in combination with the CHOICE command to set your return value, but alas, it's no longer part of windows.

So you could write a small program instead. Something that takes the desired return value as an argument, then sets and returns that as the return value:

#include <cstdio>

int main(int argc, char * argv[]) {

    if (argc == 2) {

        return strtoul(argv[1], NULL, 10);

    } else {
        return 0;
    }
}

Then in your batch file, you just call the program with the desired return value, and jump to the end.

Bill B
Interesting! That does indeed work. I really wonder what the issue with "exit /b" is...
Owen
+1  A: 

Another thing you can try is this:

set errorlevel=1
exit /b

This basically has the same effect as what @Bill suggests. The return value of the last program ran is set to the environment variable called %errorlevel% and then when you exit cmd.exe this is the value returned from the process (which is what VS reads)

shoosh
Same deal with this as with "exit /b 1": It doesn't work. But it works if I do "set errorlevel=1" then "exit".
Owen
Doesn't work if I omit the "exit" either—i.e. if I make "set errorlevel=1" the last line of the .bat.
Owen
+2  A: 

Regarding your actual question,
This page specifies the full syntax expected by VS as the output of the build tools.

shoosh
Perfect. Thank you!
Owen