如何异步重定向标准错误流而不是C#,。net中进程的标准输出流

时间:2012-10-16 17:53:30

标签: c# .net process io io-redirection

我正在用C#编写一个应用程序,在某些时候使用带有异步IO重定向的Process类将应用程序作为子进程启动,如下所示:

private void AppLaunch_Click(object sender, RoutedEventArgs e)
{

  Process appProcess = new Process();
  appProcess.StartInfo.FileName = currAppPath;
  appProcess.StartInfo.Arguments = "";

  //Setup Redirection
  appProcess.StartInfo.UseShellExecute = false;
  appProcess.StartInfo.ErrorDialog = false;
  appProcess.StartInfo.RedirectStandardError = true;
  appProcess.EnableRaisingEvents = true;
  // Attach Output Handler
  appProcess.ErrorDataReceived += appProc_DataReceived;
  appProcess.Exited += appProc_Exited;
  buildLogConsoleOutputTxtbox.AppendText(currAppPath + "\n");

  appProcess.Start();
  appProcess.BeginErrorReadLine();

}
private void appProc_DataReceived(object sender, DataReceivedEventArgs e)
{
  if (!String.IsNullOrEmpty(e.Data))
  {
    this.appendLogText(e.Data);
  }
}

private void appProc_Exited(object sender, System.EventArgs e)
{
  Process proc = (Process)sender;
  // Wait a short while to allow all console output to be processed and appended
  Thread.Sleep(40);
  this.appendLogText("\n>>");
  proc.Close();
}

private void appendLogText(string logText)
{
  // Use a delegate if called from a different thread,
  // else just append the text directly
  if (buildLogConsoleOutputTxtbox.Dispatcher.CheckAccess())
  {
    // Thread owns the TextBox
    buildLogConsoleOutputTxtbox.AppendText(logText + Environment.NewLine);
  }
  else
  {
    //Invocation Required
    appendLogCallBack appendLog = new appendLogCallBack(buildLogConsoleOutputTxtbox.AppendText);
    buildlogScrollEnd buildlogscrl = new buildlogScrollEnd(buildLogConsoleOutputTxtbox.ScrollToEnd);
    buildLogConsoleOutputTxtbox.Dispatcher.BeginInvoke(appendLog, new object[] { logText + Environment.NewLine });
    buildLogConsoleOutputTxtbox.Dispatcher.BeginInvoke(buildlogscrl);
  }

这段代码的问题在于,当我确实将 stderr 正确地重定向到我的文本框时,此重定向似乎 隐藏 进程' stdout 输出,我不想重定向!

如果我重定向stdout,我可以看到它正确重定向,但是不可能只重定向stderr而不是stdout?我已经四处查看并搜索了有关此主题的内容,但所有讨论似乎都是关于重定向标准输出...例如:How to asynchronously read the standard output stream and standard error stream at once

如果对此有任何帮助,我将不胜感激!

1 个答案:

答案 0 :(得分:2)

这是不可能的 - 输出和错误句柄同时重定向。 MSDN文章STARTUPINFO描述了STARTF_USESTDHANDLES标记。

但有一个好消息。仍然可以保留子进程输出。你只需要:

  • 重定向子流程输出
  • 附加到子进程控制台
  • 将子进程输出写回其控制台

所以在流程开始调用之后

[DllImport("Kernel32.dll", SetLastError = true) ]
static extern uint AttachConsole(int pid);

然后在DataReceived处理程序中使用简单的Console.WriteLine。