我正在为cmd编写一个包装器但是在重定向标准输入时遇到了麻烦

时间:2010-08-15 06:55:45

标签: c# .net windows winforms cmd

好的,这就是我正在做的事情 - 我想写一个.net应用程序,将标准输出重定向到richtextbox。我已经很好地工作了,但是一旦我在混合中添加标准输入,我的读取命令就会冻结。这是我表格中的相关代码。

        Shell = new Process();
        Shell.StartInfo.FileName = "cmd";

        Shell.StartInfo.UseShellExecute = false;
        Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        Shell.StartInfo.CreateNoWindow = true;

        //Shell.StartInfo.RedirectStandardInput = true;
        Shell.StartInfo.RedirectStandardOutput = true;
        Shell.StartInfo.RedirectStandardError = true;

        Shell.EnableRaisingEvents = true;
        Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
        Shell.ErrorDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);

        Shell.Start();

        Timer consoleReader = new Timer();
        consoleReader.Interval = 200;
        consoleReader.Tick += new EventHandler(consoleReader_Tick);
        consoleReader.Start();
    }

    void consoleReader_Tick(object sender, EventArgs e)
    {
        textArea.AppendText(Shell.StandardOutput.ReadToEnd());
    }

我也尝试过在Process类中使用的异步读取方法,但是,一旦我将standardinputredirect = true添加到混合中,它会在读完一行之后挂断。

任何想法的人?

[[编辑]] 好的,这是一个示例程序。我将此代码移动到控制台应用程序中以简化操作。为什么会这样?

using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;

namespace TestAsConsoleApp
{
    class Program
    {
        static Process Shell;
        static void Main(string[] args)
        {
            Shell = new Process();
            Shell.StartInfo.FileName = "cmd";

            Shell.StartInfo.UseShellExecute = false;
            Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
            Shell.StartInfo.CreateNoWindow = true;

            Shell.StartInfo.RedirectStandardInput = true;
            Shell.StartInfo.RedirectStandardOutput = true;
            Shell.StartInfo.RedirectStandardError = true;

            Shell.Start();

            Shell.EnableRaisingEvents = true;
            Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
            Shell.BeginOutputReadLine();

            Shell.WaitForExit();
        }

        static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
        {
            if (e.Data != null)
                Console.WriteLine(e.Data);
        }
    }
}

2 个答案:

答案 0 :(得分:1)

修订后的计划看起来并没有被打破。您创建一个进程请求所有要重定向的流。您可以触发创建的流程输出的异步读取。那你等一下在您的情况下,创建的cmd.exe在其输入流中不会获得任何内容,因此它不会产生任何输出。可以尝试下面的程序。运行它并给出一些命令,如dir等,它将产生输出。希望我没有误解你的问题。

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Diagnostics;

    namespace TestAsConsoleApp
    {
        class Program
        {
            static Process Shell;
            static void Main(string[] args)
            {
                Shell = new Process();
                Shell.StartInfo.FileName = "cmd";

                Shell.StartInfo.UseShellExecute = false;
                Shell.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
                Shell.StartInfo.CreateNoWindow = true;

                Shell.StartInfo.RedirectStandardInput = true;
                Shell.StartInfo.RedirectStandardOutput = true;
                Shell.StartInfo.RedirectStandardError = true;

                Shell.Start();
                //Shell.StandardInput.WriteLine("dir");

                Shell.EnableRaisingEvents = true;
                Shell.OutputDataReceived += new DataReceivedEventHandler(Shell_OutputDataReceived);
                Shell.BeginOutputReadLine();
//read input from your programs input and forward that to the created cmd 's input
                do
                {
                    string aLine = Console.ReadLine();
                    Shell.StandardInput.WriteLine(aLine);
                    if (aLine.ToLower() == "exit")
                        break;
                }while(true);

                Shell.WaitForExit();
            }

            static void Shell_OutputDataReceived(object sender, DataReceivedEventArgs e)
            {
                if (e.Data != null)
                    Console.WriteLine(e.Data);
            }
        }
    }

答案 1 :(得分:0)

如果您正在异步读取,则不需要同步读取 - 同步代码也会被破坏,因为它会一直阻塞,直到 all 收到输出为止,您不应该这样做在UI线程中执行。如果我是你,我会去寻找异步代码。

现在,你想用控制台做什么?你说标准输入引起了问题 - 你想写什么?你明确表示正在冲洗吗?