Redirection: It’s a Shell Game

I got caught in a silly little trap this morning, and it cost me an hour or so of debugging time. Usually I enjoy debugging, when the error I am chasing is legit, meaning a reasonably good programmer could have caused it. But then there are those times when I just screw myself by being stupid, and that’s irritating. The bug in question shouldn’t have taken an hour to fix, but unfortunately the only way to debug this particular program is build-commit-push-run-read log. You get the picture.

Anyway, I was using Process.Start() to spawn a console application from within a job running on a service framework. I wanted to redirect the output of the console application to a log file. You can also redirect console output back to a stream in the spawning code, which is slick, but in this case there is a lot of output, and a log is really the best place for it. From the command line the operation might look like this:

c:\myapp.exe -A arg1 -B arg2 -C arg3 > c:\somedir\myapp.log

Pretty straightforward, and it works great. Having tested this on the command line I translated it into the C# code for our app, and it looked something like this:

Process.Start(“myapp.exe”, “-A arg1 -B arg2 -C arg3 > c:\somedir\myapp.log”);

The first parameter is the executable name, the second is the arguments. When I executed this code the errorlevel indicated myapp.exe didn’t understand the arguments it was passed. What? They’re the same arguments I just passed you on the command line, and they worked fine! Copy the text to the command line. Run it. Yep, it works fine.

But not when spawned using Process.Start(). You smart people probably already see what I did wrong. The problem is that standard output redirection using the > operator is not something myapp.exe knows how to do. It’s something cmd.exe knows how to do. When I ran the program from a command prompt I was running it within an instance of cmd.exe. But when I spawned it using the code above there was no instance of cmd.exe running, and so the redirection operator was just another argument passed to myapp.exe. The correct method is:

Process.Start(“cmd.exe”, “/c myapp.exe -A arg1 -B arg2 -C arg3 > c:\somedir\myapp.log”);

Sometimes, I are not that bright.

Leave a Reply

Your email address will not be published. Required fields are marked *