代码之家  ›  专栏  ›  技术社区  ›  amazedsaint

C中的交互式控制台I/O包装器/拦截器-问题是什么?

  •  3
  • amazedsaint  · 技术社区  · 15 年前

    就我目前的情况来看,我无法从控制台可靠地读回数据。有什么快速的提示吗?

    public class ConsoleInterceptor
    {
        Process _interProc;
    
        public event Action<string> OutputReceivedEvent;
    
        public ConsoleInterceptor()
        {
            _interProc = new Process();
            _interProc.StartInfo = new ProcessStartInfo("cmd");
            InitializeInterpreter();
        }
    
        public ConsoleInterceptor(string command)
        {
            _interProc = new Process();
            _interProc.StartInfo = new ProcessStartInfo(command);
            InitializeInterpreter();
        }
    
        public Process InterProc
        {
            get
            {
                return _interProc;
            }
        }
    
        private void InitializeInterpreter()
        {
            InterProc.StartInfo.RedirectStandardInput = true;
            InterProc.StartInfo.RedirectStandardOutput = true;
            InterProc.StartInfo.RedirectStandardError = true;
            InterProc.StartInfo.CreateNoWindow = true;
            InterProc.StartInfo.UseShellExecute = false;
            InterProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            bool started = InterProc.Start();
    
            Redirect(InterProc.StandardOutput);
            Redirect(InterProc.StandardError);
    
        }
    
        private void Redirect(StreamReader input)
        {
            new Thread((a) =>
            {
                var buffer = new char[1];
                while (true)
                {
                    if (input.Read(buffer, 0, 1) > 0)
                        OutputReceived(new string(buffer));
                };
            }).Start();
        }
    
        private void OutputReceived(string text)
        {
            if (OutputReceivedEvent != null)
                OutputReceivedEvent(text);
        }
    
    
        public void Input(string input)
        {
            InterProc.StandardInput.WriteLine(input);
            InterProc.StandardInput.Flush();
        }
    }
    

    我要做的是什么?这里是一个小用例。假设我有两个文本框。

    //Create my interceptor
     ConsoleInterceptor interc = new ConsoleInterceptor("cmd");
    //Show the output in a textbox
         interc.OutputReceivedEvent += (data) =>
                    {
                        this.Invoke(new Action<string>((s)=> this.textBoxOut.Text += s) ,data);
                    };
    
    
    
     //Capture user input and pass that to the above interceptor
      private void textInput_KeyDown(object sender, KeyEventArgs e)
            {
                if (e.KeyCode == Keys.Enter)
                {
                    interc.Input(textInput.Text);
                }
            }
    
    2 回复  |  直到 15 年前
        1
  •  1
  •   Sam Holder Brian Adams    15 年前

    您可以将处理程序附加到 Process.OutputDataReceived Event ,在调用BeginOutputReadLine之后,当进程向重定向的StandardOutput流写入一行时(您已经这样做了),它将被引发。

        2
  •  0
  •   Stephen Cleary    15 年前

    为了与任何控制台进程完全兼容,您需要三个独立的线程:一个写入stdin,一个从stdout读取,一个从stderr读取。这些是你的主线之外的。示例代码只有所需的三个线程中的一个(stdout)。

    推荐文章