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

C# 将控制台输出重定向到单独程序中的文本框,c#,.net,winforms,textbox,console,C#,.net,Winforms,Textbox,Console,我正在开发一个Windows窗体应用程序,它要求我调用一个单独的程序来执行一项任务。该程序是一个控制台应用程序,我需要将标准输出从控制台重定向到程序中的文本框 从应用程序执行程序没有问题,但我不知道如何将输出重定向到应用程序。我需要在程序使用事件运行时捕获输出 在我的应用程序停止运行并且文本以随机间隔不断更改之前,控制台程序不会停止运行。我试图做的只是挂接控制台的输出以触发事件处理程序,然后该事件处理程序可用于更新文本框 我正在使用C#编写程序,并使用.NET框架进行开发。原始应用程序不是.NE

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

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

在我的应用程序停止运行并且文本以随机间隔不断更改之前,控制台程序不会停止运行。我试图做的只是挂接控制台的输出以触发事件处理程序,然后该事件处理程序可用于更新文本框

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

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

    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);
    }
这对我很有用:

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
}

您可以使用以下代码

        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();

我在(开源项目)中添加了许多帮助器方法,允许您通过控制台输出和输入轻松编写与另一个进程的交互脚本(请参阅)


允许查看当前进程(在现有控件或弹出窗口中)的控制台输出的API可能对您也很有用。有关更多详细信息,请参阅本博客:(本博客还包含如何使用新进程的控制台输出的详细信息)

感谢Marc Maxham为我节省时间的回答

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

下面是我对代码的修改,其中
txtOut
是一个WPF只读文本框

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) ));
}

如果“C:\ConsoleApp.exe”不是.Net应用程序,则不会运行该应用程序!我发现有时(在程序退出时)e.Data为空,所以您必须检查e.Data!=空+我第一次看到这种东西是在EditPlus中。现在我可以在我的.NET程序中执行此操作。谢谢你,伙计!我们不需要设置
UseShellExecute=false
来重定向输出吗?谢谢Mark,不过,将其与已编译的Ruby脚本一起用作仅具有命令输出的可执行文件并不能完全按照预期工作。首先,正如Jon所提到的,您需要proc.StartInfo.UseShellExecute=false。。。然后,您可以在程序完成后立即通过BeginOutputReadLine()发送所有数据。我有一种感觉,ReadLine实际上需要行而不是文本,因此,如果可执行文件发送的返回/新行代码与环境不匹配,则在应用程序完成之前,它不会捕获OutputDataReceived中的任何数据。如果在生产中使用此代码,请记住
过程
是一次性的,还要记住分离事件处理程序(
proc.ErrorDataReceived-=proc_DataReceived
等)?