【问题标题】:Redirect console output to textbox in separate program将控制台输出重定向到单独程序中的文本框
【发布时间】:2010-09-29 18:14:30
【问题描述】:

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

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

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

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

编辑: 这是我正在尝试做的示例代码。在我的最终应用程序中,我将使用更新 TextBox 的代码替换 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);
    }

【问题讨论】:

  • InputDataReceived在哪里?

标签: c# .net winforms textbox console


【解决方案1】:

这对我有用:

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
}

【讨论】:

  • 我发现有时(在程序退出时)e.Data 为空,因此您必须检查 e.Data != null 是否!
  • +1 我第一次看到这种东西是在 EditPlus 中。现在我可以在我的 .NET 程序中做到这一点。谢谢大佬!
  • 我们不需要设置UseShellExecute = false来重定向输出吗?
  • 感谢 Mark,但是将其与已编译的 Ruby 脚本一起用作仅具有命令输出的可执行文件并不能按预期工作。首先,正如所有行业的乔恩所提到的,你需要有 proc.StartInfo.UseShellExecute = false; ...然后您可以在程序完成后立即通过 BeginOutputReadLine() 发送所有数据。我有一种感觉 ReadLine 字面上需要行而不是文本,所以如果可执行文件发送的返回/新行代码与环境不匹配,它不会在应用程序完成之前捕获 OutputDataReceived 中的任何数据。
  • 如果您在生产环境中使用此代码,请记住 Process 是一次性的,还记得分离事件处理程序(proc.ErrorDataReceived -= proc_DataReceived 等)。
【解决方案2】:

您可以使用以下代码

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

【讨论】:

  • 如果“C:\ConsoleApp.exe”不是 .Net 应用程序,它将无法运行!
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

    正如 Jon of All Trades 所注意到的,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) ));
    }
    

    【讨论】:

      猜你喜欢
      • 2011-02-22
      • 2010-10-08
      • 2013-11-14
      • 2011-05-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多