C# 将控制台输出重定向到单独程序中的文本框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/415620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 02:33:44  来源:igfitidea点击:

Redirect console output to textbox in separate program

c#.netwinformstextboxconsole

提问by

I'm developing an Windows Forms application that requires me to call a separate program to perform a task. The program is a console application and I need to redirect standard output from the console to a TextBox in my program.

我正在开发一个 Windows 窗体应用程序,它需要我调用一个单独的程序来执行任务。该程序是一个控制台应用程序,我需要将控制台的标准输出重定向到我程序中的 TextBox。

I have no problem executing the program from my application, but I don't know how to redirect the output to my application. I need to capture output while the program is running using events.

我从我的应用程序执行程序没有问题,但我不知道如何将输出重定向到我的应用程序。我需要在程序运行时使用事件捕获输出。

The console program isn't meant to stop running until my application stops and the text changes constantly at random intervals. What I'm attempting to do is simply hook output from the console to trigger an event handler which can then be used to update the TextBox.

控制台程序不会停止运行,直到我的应用程序停止并且文本以随机间隔不断变化。我正在尝试做的只是从控制台挂钩输出以触发事件处理程序,然后可以使用该事件处理程序更新 TextBox。

I am using C# to code the program and using the .NET framework for development. The original application is not a .NET program.

我使用 C# 编写程序并使用 .NET 框架进行开发。原始应用程序不是 .NET 程序。

EDIT: Here's example code of what I'm trying to do. In my final app, I'll replace Console.WriteLine with code to update the TextBox. I tried to set a breakpoint in my event handler, and it isn't even reached.

编辑:这是我正在尝试做的示例代码。在我的最终应用程序中,我将用代码替换 Console.WriteLine 以更新 TextBox。我试图在我的事件处理程序中设置一个断点,但它甚至没有达到。

    void Method()
    {
        var p = new Process();
        var path = @"C:\ConsoleApp.exe";

        p.StartInfo.FileName = path;
        p.StartInfo.UseShellExecute = false;
        p.OutputDataReceived += p_OutputDataReceived;

        p.Start();
    }

    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e)
    {
        Console.WriteLine(">>> {0}", e.Data);
    }

采纳答案by Mark Maxham

This works for me:

这对我有用:

void RunWithRedirect(string cmdPath)
{
    var proc = new Process();
    proc.StartInfo.FileName = cmdPath;

    // set up output redirection
    proc.StartInfo.RedirectStandardOutput = true;
    proc.StartInfo.RedirectStandardError = true;    
    proc.EnableRaisingEvents = true;
    proc.StartInfo.CreateNoWindow = true;
    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;

    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    // output will be in string e.Data
}

回答by Ahmed Said

You can use the following code

您可以使用以下代码

        MemoryStream mem = new MemoryStream(1000);
        StreamWriter writer = new StreamWriter(mem);
        Console.SetOut(writer);

        Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe");
        assembly.EntryPoint.Invoke(null, null);
        writer.Close();

        string s = Encoding.Default.GetString(mem.ToArray());
        mem.Close();

回答by Dinis Cruz

I've added a number of helper methods to the O2 Platform(Open Source project) which allow you easily script an interaction with another process via the console output and input (see http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs)

我在O2 平台(开源项目)中添加了许多辅助方法,允许您通过控制台输出和输入轻松编写与另一个进程的交互脚本(请参阅http://code.google.com/p/o2platform/源/浏览/主干/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs)

Also useful for you might be the API that allows the viewing of the console output of the current process (in an existing control or popup window). See this blog post for more details: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/(this blog also contains details of how to consume the console output of new processes)

同样对您有用的可能是允许查看当前进程的控制台输出(在现有控件或弹出窗口中)的 API。有关更多详细信息,请参阅此博客文章:http: //o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/(此博客还包含有关如何使用的详细信息新进程的控制台输出)

回答by LauLo

Thanks to Marc Maxham for his answer that save me time !

感谢 Marc Maxham 的回答,节省了我的时间!

As Jon of All Trades notice it, UseShellExecutemust be set to false in order to redirect IO streams, otherwise the Start()call throws an InvalidOperationException.

正如 Jon of All Trades 所注意到的,UseShellExecute必须设置为 false 才能重定向 IO 流,否则Start()调用会抛出一个InvalidOperationException.

Here is my modification of the code where txtOutis a WPF readonly Textbox

这是我对代码的修改,其中txtOutWPF 只读文本框

void RunWithRedirect(string cmdargs)
{
    var proc = new Process()
    {
        StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs)
        {
            RedirectStandardOutput = true,
            RedirectStandardError = true,
            CreateNoWindow = true
        },
        EnableRaisingEvents = true
    };

    // see below for output handler
    proc.ErrorDataReceived += proc_DataReceived;
    proc.OutputDataReceived += proc_DataReceived;
    proc.Start();

    proc.BeginErrorReadLine();
    proc.BeginOutputReadLine();

    proc.WaitForExit();
}

void proc_DataReceived(object sender, DataReceivedEventArgs e)
{
    if (e.Data != null)
        Dispatcher.BeginInvoke(new Action( () => txtOut.Text += (Environment.NewLine + e.Data) ));
}