System.Diagnostics.Process / .BAT file / always returns exit code 0

E

eva.monsen

I'm trying to run a .BAT file using System.Diagnostics.Process. I'm
having trouble getting Process.ExitCode to match up with what the .BAT
file returns.

Here are the contents of
C:\temp\ConsoleApplication1\ConsoleApplication1\test1.bat:

exit /B 6

Here is some C# code:

Process p = new Process();
p.StartInfo.FileName =
@"C:\temp\ConsoleApplication1\ConsoleApplication1\test1.bat";
// this doesn't work either:
//p.StartInfo.FileName = @"c:\windows\system32\cmd.exe";
//p.StartInfo.Arguments = @"/c
c:\temp\ConsoleApplication1\ConsoleApplication1\test1.bat";
p.Start();
p.WaitForExit();
Console.WriteLine("Exit code = {0}", p.ExitCode);

I would expect this program to print "Exit code = 6"...
But it actually prints "Exit code = 0".

Why?

Thanks in advance for your input!
Eva Pierce Monsen
 
E

eva.monsen

To somewhat answer my own question, I finally found this similar post:

http://groups.google.com/group/micr...cs.process+errorlevel&rnum=1#13ef61d0db8a24da

If I change test1.bat from "exit /B 6" to "exit 6", I get the expected
ExitCode.

But I'm unhappy with this; say someone wants to actually call test1.bat
from a command prompt (which in my real life app is always the case)?
"exit 6" will cause the command prompt window to close.

Can anyone think of a way to have test1.bat callable both from command
prompt and from the C# program and get a happy result either way?

Eva
 
B

Barry Kelly

I'm trying to run a .BAT file using System.Diagnostics.Process. I'm
having trouble getting Process.ExitCode to match up with what the .BAT
file returns.

Here are the contents of
C:\temp\ConsoleApplication1\ConsoleApplication1\test1.bat:

exit /B 6

This, in fact, does not work. You can test it in cmd with the || or &&
operators:

test1.bat || echo "Non-zero result"

(prints nothing)

or

test1.bat && echo "Zero result"

(prints "Zero result")

This shows that even CMD notices that the batch file does in fact return
with a zero result.

You can get around it by writing a simple program which returns the
desired exit code. The exit code of a batch file is the exit code of the
last command executed in the batch file. So, write a program called
"return" or something, like this:

---8<---
class App
{
static int Main(string[] args)
{
if (args.Length == 0)
return 0;
return int.Parse(args[0]);
}
}
--->8---

.... and call this with 'return 6' or whatever result you want.

-- Barry
 
E

eva.monsen

Thanks Barry - my mistake. I am becoming more educated in
distinguishing DOS "errorlevel" vs. process return code. Is it correct
to suspect that if I set "errorlevel" in a .BAT file, it would be
inaccessible from a C# program invoking it?

Good suggestion on writing a program to return the exit code; however,
the real-life .BAT file must eventually be able to run on machines that
do not have .NET installed. I wanted to unit-test the .BAT file with
NUnit, hence the C# code in my original post.

Of course I could do what you suggested in VB6 or C++, but... what a
mess; all I want to do is run a simple script. I think the take-home
lesson is don't use DOS scripts...

Thanks again,
Eva Pierce Monsen

Barry said:
I'm trying to run a .BAT file using System.Diagnostics.Process. I'm
having trouble getting Process.ExitCode to match up with what the .BAT
file returns.

Here are the contents of
C:\temp\ConsoleApplication1\ConsoleApplication1\test1.bat:

exit /B 6

This, in fact, does not work. You can test it in cmd with the || or &&
operators:

test1.bat || echo "Non-zero result"

(prints nothing)

or

test1.bat && echo "Zero result"

(prints "Zero result")

This shows that even CMD notices that the batch file does in fact return
with a zero result.

You can get around it by writing a simple program which returns the
desired exit code. The exit code of a batch file is the exit code of the
last command executed in the batch file. So, write a program called
"return" or something, like this:

---8<---
class App
{
static int Main(string[] args)
{
if (args.Length == 0)
return 0;
return int.Parse(args[0]);
}
}
--->8---

... and call this with 'return 6' or whatever result you want.

-- Barry
 
B

Barry Kelly

Thanks Barry - my mistake. I am becoming more educated in
distinguishing DOS "errorlevel" vs. process return code. Is it correct
to suspect that if I set "errorlevel" in a .BAT file, it would be
inaccessible from a C# program invoking it?

Generally, you set the errorlevel by executing a program. If that
program is the last command in the file, then it would be accessible to
a C# program invoking it.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top