• 重定向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);
                }
        }
        
    }


     

  • 相关阅读:
    e.printStackTrace()打印在哪里以及如何e.printStackTrace()的内容打印在日志中
    oracle分组并在组内排序
    Java.util.Calendar类
    oracle分页查询
    两个map合并
    【自动化测试】无需图形界面环境下的浏览器开源项目
    【运维工具】logrotate 日志管理神器
    如何查看google chrome 插件源码
    phpexcel 读取数据
    常用开发资源收集
  • 原文地址:https://www.cnblogs.com/flaaash/p/3084841.html
Copyright © 2020-2023  润新知