重定向Console输出到文本框

很多时候,我们需要捕获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);
            }
    }
    
}

 

 

 

 

 

 


 

转载于:https://www.cnblogs.com/flaaash/archive/2013/05/18/3084841.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值