Is there a better way to redirect stdout in C++/CLI then with system()?
In 2 parts of the C++/CLI code I'm working on, the program needs to run a different executable and have its STDOUT output redirected to a file. Its being attempted in 2 different ways, and only one of the 2 currently works. The program is being run on Windows XP.
The first section assembles a long char* that ends up looking something like this:
char* exepath = "start/B /D\\root\\bin \\root\\bin\\process.exe 1>\\root\\logs\\process_STDOUT.txt"
Then the code simply calls
Status = system(exepath);
This works fine: It both runs process.exe and creates the process_STDOUT.txt file as expected.
The second section tries to do the same using a Proces开发者_运维技巧sStartInfo object instead. It successfully starts process.exe, but has not been creating the redirected output .txt file. Here is a simplified version of that code:
Process p = gcnew Process();
ProcessStartInfo^ s = gcnew ProcessStartInfo();
s->FileName = "\\root\\bin\\process.exe";
s->WindowStyle = ProcessWindowStyle::Hidden;
s->CreateNoWindow = true;
s->UseShellExecute = false;
s->Arguments = "1>\\root\\logs\\process_STDOUT.txt";
p->StartInfo = s;
p->Start();
Am I doing something wrong with this code? And if not, is going back to just calling system(exepath) my only option or are there any others?
The system
function invokes the system's command-line interpretter, which on Windows is usually cmd.exe. That's the program that parses the I/O-redirection syntax. The program you're starting has no idea what >
means; it interprets that as the first character of an actual command-line argument. (Think about it — have you ever written command-line-redirection code in your command-line programs? No, of course not. Neither did the author of process.exe.)
So that's why your ProcessStartInfo
method doesn't redirect I/O. For that, see the question here about redirecting stdin and stdout in .Net.
Since you're redirecting output to a file anyway, your current system
code should be fine. The more programmatic ways of redirecting are necessary when you want to collect the output within your program instead of a file.
Check out this article. Noteworthy:
/* Setup Redirect */
processStartInfo.RedirectStandardError = true;
processStartInfo.RedirectStandardInput = true;
processStartInfo.RedirectStandardOutput = true;
/* Capture Output */
StreamWriter inputWriter = process.StandardInput;
StreamReader outputReader = process.StandardOutput;
StreamReader errorReader = process.StandardError;
process.WaitForExit();
Passing "1>\\root\\logs\\process_STDOUT.txt"
as an argument is not the same as redirecting
The "pipe command" is not passed as a parameter to the program; the shell interprets it and the program itself has no idea that its output is being redirected to a file. So you don't want to pass stuff like that as an argument.
However, the Program
class has StandardOutput
and StandardError
stream properties to help you capture output. You simply need to specify (in your ProcessStartInfo
object) that you want to redirect output.
s->RedirectStandardOutput = true;
s->RedirectStandardError = true;
Past that point, you'll be able to use p->StandardOutput
and p->StandardError
to get the output of the stream.
精彩评论