C# 在控制台进程完成之前,重定向标准输出不会激发

C# 在控制台进程完成之前,重定向标准输出不会激发,c#,winforms,visual-studio,console-application,outputstream,C#,Winforms,Visual Studio,Console Application,Outputstream,我遇到了一个奇怪的问题。我已经使用Visual Studio 2012/13用C编写了一个windows窗体应用程序。“我的应用程序”打开一个控制台应用程序,并在其运行时从中捕获标准和错误输出,然后将该输出打印到windows窗体中的文本框中。它曾经工作得很好,但我一定是改变了一些不小心导致该功能停止工作的东西 它现在只在控制台应用程序完成并退出后,在windows窗体中打印控制台应用程序的输出。我一直在用我的头撞这个有一点现在,我不知所措。我从VisualStudio2012升级到2013年,

我遇到了一个奇怪的问题。我已经使用Visual Studio 2012/13用C编写了一个windows窗体应用程序。“我的应用程序”打开一个控制台应用程序,并在其运行时从中捕获标准和错误输出,然后将该输出打印到windows窗体中的文本框中。它曾经工作得很好,但我一定是改变了一些不小心导致该功能停止工作的东西

它现在只在控制台应用程序完成并退出后,在windows窗体中打印控制台应用程序的输出。我一直在用我的头撞这个有一点现在,我不知所措。我从VisualStudio2012升级到2013年,但项目没有改变、升级或类似的事情,所以我不认为这是罪魁祸首。任何帮助都将不胜感激

我相信我已经设置了适当的代码,以便在打印时捕获输出。无论如何,这都是正常工作的:

transporterProcess.StartInfo.ErrorDialog = true;
transporterProcess.StartInfo.UseShellExecute = false;
transporterProcess.StartInfo.CreateNoWindow = true;
transporterProcess.StartInfo.RedirectStandardOutput = true;
transporterProcess.StartInfo.RedirectStandardError = true;
transporterProcess.EnableRaisingEvents = true;
transporterProcess.OutputDataReceived += new DataReceivedEventHandler(printOutput);
transporterProcess.ErrorDataReceived += new DataReceivedEventHandler(printError);
transporterProcess.Exited += new EventHandler(process_Exited);

...

transporterProcess.Start();
transporterProcess.BeginOutputReadLine();
transporterProcess.BeginErrorReadLine();

private void printOutput(object sendingProcess, DataReceivedEventArgs outLine)
{
    if (!String.IsNullOrEmpty(outLine.Data))
    {   // output is a global StringBuilder object
        output.Clear();
        output.Append(outLine.Data + Environment.NewLine);
        string update = output.ToString();
        updateTextfromStandardOutput = new Thread(new ThreadStart(() => this.ThreadProcSafeStandardOutput(update)));
        this.updateTextfromStandardOutput.Start();
    }
}

    private void printError(object sendingProcess,
        DataReceivedEventArgs outLine)
    {
       // pretty much identical to the above code
    }

    private void ThreadProcSafeStandardOutput(string update)
    {
        this.setText(update);
    }

    private void ThreadProcSafeStandardError(string update)
    {
        this.setText(update);
    }

    private void setText(string text)
    {
        if (tbxOutput.InvokeRequired || listViewFilesToTransfer.InvokeRequired)
        {
            setTextCallback d = new setTextCallback(setText);
            tbxOutput.Invoke(d, new object[] { text });
        }
        else
        {
          ...
提前谢谢

您需要将EnableRaisingEvents设置为true


我将输出刷新添加到被调用的应用程序中,这解决了@HansPassant提出的问题,虽然感觉有点像绷带,但至少它是有效的

您是否在ProcessStartInfo对象上设置了UseShellExecute=false、RedirectStandardOutput=true和RedirectStandardError=true?这是完全正常的。重定向程序将其输出写入内部缓冲区。如果它没有写入足够的文本来填充缓冲区的容量,并且它本身没有强制缓冲区刷新,那么在程序退出时必须刷新缓冲区之前,您不会看到任何内容。如果您没有程序的源代码,您将无能为力。@RichardDeeming抱歉,我添加了问题中遗漏的代码。@HansPassant是否有办法在被调用的进程结束之前清除调用应用程序的缓冲区?我可以访问控制台进程,它调用它是用C++编写的,如果这有帮助。@ HSPSPANT我把输出刷新添加到被调用的应用程序中,这样就解决了问题,这是很好的,但是感觉就像绷带而不是正确的修复。我以前不必这么做,有什么可以改变的?是否有其他方法可以请求被调用的应用程序执行此操作?很抱歉,我没有这样做,但我没有在示例代码中添加这一点。我把它加在上面了。谢谢哦,我的意思是说我的代码中已经有了这一点,而不是说这是对问题的修复。可悲的是,它仍然是坏的:你能分享你的新代码吗?我也有同样的问题!
transporterProcess.EnableRaisingEvents = true;