重定向Console输出到文本框

摘要:
txtBox.BegginInvoke(动作);}公共重写System.Text.Encoding Encoding{get{return System.Text.Encoding.UTF8;

很多时候,我们需要捕获Console输出,然后在文本框等控件中显示。
例如SnippetCompiler就实现了编译源代码并将结果在下面的ListView显示的功能。
Console.SetOut(TextWriter)设置Console输出重定向,这样我们需要写一个TextWriter的派生类,这个类的构造函数我们传入要定向目标控件的引用,然后在 public override void Write(char value) 中修改引用控件的BeginInvoke方法挂一个Delegate关联控制台输出流到控件。代码如下,足够精简了。

using System;
using System.Windows.Forms;

namespace Console2TextBox
{
        public class TextBoxWriter : System.IO.TextWriter
        {
            TextBox txtBox;
            delegate void VoidAction();
            
            public TextBoxWriter(TextBox box)
            {
                txtBox = box; //transfer the enternal TextBox in
            }
            
            public override void Write(char value)
            {
                //base.Write(value);//still output to Console
                VoidAction action = delegate{
                    txtBox.AppendText(value.ToString());
                };
                txtBox.BeginInvoke(action);
            }
            
            public override System.Text.Encoding Encoding
            {
                getreturn System.Text.Encoding.UTF8;}
            }
        }    
        
        public class Program
        {
            public static void Main()
            {
                //TextBox, receive the output from Console
                TextBox txtOutput = new TextBox{Multiline = true};
                txtOutput.Dock = System.Windows.Forms.DockStyle.Fill;
                //Timer output current time to Console
                var timer = new Timer{ Enabled = true, Interval = 1000};
                timer.Tick += delegate{
                    System.Console.WriteLine(DateTime.Now.TimeOfDay.ToString());
                };
                //redirect console output to textbox
                Console.SetOut(new TextBoxWriter(txtOutput));
                //Form
                Form form = new Form();
                form.Controls.Add(txtOutput);
                Application.Run(form);
            }
    }
    
}

以上是将当前Console.SetOut重定向到当前Windows.Forms.Controls,如果用Process.Start启动的另外的进程,就不是那么回事了。
首先,同步方式:首先 StandardInput.WriteLine(strCmd) 向标准输入提供消息,然后用 StandardOutput.ReadToEnd();读取消息;
但可能ReadToEnd将一直阻塞直到启动进程结束或者输出流关闭才能读到数据。

    public static void Main()
    {
        var startInfo = new System.Diagnostics.ProcessStartInfo{
            FileName="cmd.exe"
            UseShellExecute =  false,  // 是否使用外壳程序
            RedirectStandardInput =  true,  // 重定向输入流
            RedirectStandardOutput= true,  //重定向输出流
            RedirectStandardError= true,  //重定向错误流
            CreateNoWindow = true   //是否在新窗口中启动该进程的值 
        };        
        System.Diagnostics.Process cmd =  new System.Diagnostics.Process();
        cmd.StartInfo = startInfo;

        string strCmd =  "ping www.baidu.com \r\n";
        strCmd += "exit\r\n";//cmd只有关闭后才关闭输出流,否则ReadToEnd将一直等待    
        cmd.Start();
        cmd.StandardInput.WriteLine(strCmd);//向CMD输入ping命令和Exit命令
        
//获取输出信息 : 执行到ReadToEnd将一直阻塞直到cmd进程结束(输出流关闭)!!!
        string output = cmd.StandardOutput.ReadToEnd();
        System.Windows.Forms.MessageBox.Show(output);
    }

采用异步方式能更好的实现这一功能,下面演示 ping 命令的异步效果,你将看到数据是一行一行输出,而不是像上面等到ping命令退出后忽然输出所有数据.

using System;
using System.Diagnostics;
using System.Windows.Forms;

namespace Console2TextBox
{      public class FormConsoleRedirect : Form
        {
            TextBox txtOutput;
            public Process cmd;
            
            public FormConsoleRedirect()
            {
                //TextBox, receive the output from Console
                txtOutput = new TextBox{Multiline = true};
                txtOutput.Dock = System.Windows.Forms.DockStyle.Fill;
                 //redirect console output to textbox
                System.Diagnostics.ProcessStartInfo info = new System.Diagnostics.ProcessStartInfo{
                    FileName="cmd",
                    UseShellExecute=false,
                    CreateNoWindow=true,
                    RedirectStandardInput = true,
                    RedirectStandardError=true,
                    RedirectStandardOutput=true
                };
                cmd = new Process();
                int i=0;
                cmd.OutputDataReceived +=(s,e)=>{
                    string infoText = string.Format("{0,4 }:{1}\r\n",i++,e.Data);
                    txtOutput.AppendText(infoText); 
                };                
                cmd.ErrorDataReceived +=(s,e)=>{
                    string infoText = string.Format("{0,4 }:{1}\r\n",i++,e.Data);
                    txtOutput.AppendText(infoText); 
                };
                cmd.StartInfo = info;
                cmd.EnableRaisingEvents = true;
                cmd.Start();
                cmd.BeginOutputReadLine();
                cmd.BeginErrorReadLine();
                
                //form.Controls
                this.Controls.Add(txtOutput);
            }
            
            
        }
        public class Program
        {
            public static void Main()
            {
                //Form
                FormConsoleRedirect form = new FormConsoleRedirect();
                string strCmd =  "ping www.163.com \r\nExit\r\n";                
                form.cmd.StandardInput.WriteLine(strCmd);
                Application.Run(form);
            }
    }
    
}


 

免责声明:文章转载自《重定向Console输出到文本框》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇音频编码器vue $forceUpdate()强制刷新下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux多进程编程

进程的状态 Linux进程有7种基础状态(两种running算一种),除了traced都可以用$ps命令查看,$ps可以查看的进程状态如下,更多进程状态信息参见Linux Process VS Thread VS LWPR running or runnable (on run queue)D uninterruptible sleep (usually...

分享一个Winform里面的HTML编辑控件Zeta HTML Edit Control,汉化附源码

我们知道,Web开发上有很多HTML的编辑控件,如FCKEditor、CKEditor、kindeditor等等,很多都做的很好,而虽然Winform里面有WebBrowser控件,但是默认这个控件是不允许编辑内容的,可以显示网页而已。Winform开发里面,有些使用RichTextBox控件来编辑HTML,也有一些结合WebBrowser控件来实现内容的...

[阮一峰]Linux 守护进程的启动方法

"守护进程"(daemon)就是一直在后台运行的进程(daemon)。 本文介绍如何将一个 Web 应用,启动为守护进程。 一、问题的由来 Web应用写好后,下一件事就是启动,让它一直在后台运行。 这并不容易。举例来说,下面是一个最简单的Node应用server.js,只有6行。 var http = require('http'); http...

配置IIS应用程序池(转载)

IIS 6的核心在于工作进程隔离模式,而应用程序池则是定义工作进程如何进行工作,因此,可以说应用程序池是整个IIS 6的核心。 和IIS 5中只能使用单个应用程序池不同,工作在工作进程隔离模式的IIS 6可以创建多个应用程序池,不同的应用程序池之间是完全隔离的,某个应用程序池停止服务时不会影响到其他应用程序池。 在使用应用程序池之前,你应该确定你所需要的...

Android Native Hook技术(一)

原理分析 ADBI是一个著名的安卓平台hook框架,基于 动态库注入 与 inline hook 技术实现。该框架主要由2个模块构成:1)hijack负责将so注入到目标进程空间,2)libbase是注入的so本身,提供了inline hook能力。 源码目录中的example则是一个使用ADBI进行hook epoll_wait的示例。 hijack h...

delphi XE 學習筆記二:TThread.CreateAnonymousThread

TThread.CreateAnonymousThread(方法名或者匿名方法).Start(); procedure TForm1.Button1Click(Sender:TOBject); begin   TThread.CreateAnonymousThread(     procedure()     begin       //do somthi...