简体   繁体   English

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

[英]How to asynchronously redirect ONLY standard error stream and not standard output stream of a process in C#, .net

I am writing an application in C# that at some point starts an application as a child process using the Process class with Asynchronous IO redirection as shown below: 我正在用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);
  }

The Problem with this piece of code is that while I do get the stderr redirected properly to my textbox, This redirection seems to hide the process' stdout output, which I don't want redirected! 这段代码的问题在于,尽管我确实将stderr正确地重定向到了我的文本框,但是这种重定向似乎隐藏了进程的stdout输出,我不想将其重定向!

If I redirect stdout, I can see it redirected properly, but is it impossible to just redirect stderr and not stdout? 如果我重定向了stdout,我可以看到它正确地重定向了,但是仅重定向stderr而不是stdout是不可能的吗? I have looked around and googled regarding this topic but all discussions seem to be regarding redirecting stdout ... such as this : How to asynchronously read the standard output stream and standard error stream at once 我到处寻找有关此主题的信息,但所有讨论似乎都是关于重定向stdout ...这样的: 如何立即异步读取标准输出流和标准错误流

I would be grateful for any help regarding this! 对此我将不胜感激!

That is not possible as is - output and error handles are redirected simultaneously. 这是不可能的-输出和错误句柄被同时重定向。 MSDN article STARTUPINFO describes STARTF_USESTDHANDLES flag. MSDN文章STARTUPINFO描述了STARTF_USESTDHANDLES标志。

But there is a good news. 但是有个好消息。 Preserving child process output is still possible. 仍然可以保留子进程的输出。 You just have to: 您只需要:

  • redirect child process output 重定向子进程输出
  • attach to child process console 附加到子进程控制台
  • write child process output back to its console 将子进程的输出写回到其控制台

So right after process start invoke 所以在流程开始调用之后

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

and then use simple Console.WriteLine in your DataReceived handler. 然后在您的DataReceived处理程序中使用简单的Console.WriteLine。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM