从控制台应用程序发送输入/获取输出(C#/ WinForms)

Zac*_*ach 2 c# processstartinfo redirectstandardoutput

我有一个包含3个控件的表单:

  1. 用户输入命令以发送到控制台应用程序的文本框,
  2. 用于确认要发送的命令的按钮
  3. 一个只读文本框,用于显示应用程序的输出.

我想要的是让用户在第一个文本框中输入命令,按下按钮以通过第二个文本框输入和接收反馈.

我知道如何使用ProcessStartInfo.RedirectStandardOutput,但是,当我使用时,应用程序挂起StandardOutput.ReadToEnd().

我看了一下异步Process.BeginOutputReadLine()但是,即使我的应用程序没有挂起,不知何故我在文本框中没有得到任何响应,它什么也没做.

这是我的代码:

public partial class MainForm : Form
{

    private void MainForm_Load(object sender, EventArgs e)
    {
        InitializeInterpreter();
    }

    private void InitializeInterpreter()
    {
        InterProc.StartInfo.UseShellExecute = false;
        InterProc.StartInfo.FileName = "app.exe";
        InterProc.StartInfo.RedirectStandardInput = true;
        InterProc.StartInfo.RedirectStandardOutput = true;
        InterProc.StartInfo.RedirectStandardError = true;
        InterProc.StartInfo.CreateNoWindow = true;
        InterProc.OutputDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);

        InterProc.Start();
    }

    private static void InterProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        if (!String.IsNullOrEmpty(outLine.Data))
        {
           OutputTextBox.Append(Environment.NewLine + outLine.Data);
        }
    }

    private void Enterbutton_Click(object sender, EventArgs e)
    {
        InterProc.StandardInput.Write(CommandtextBox.Text);
        InterProc.BeginOutputReadLine();
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么办法让我顺利运行吗?谢谢.

McK*_*Kay 6

如果你想要一些互动的东西,我得到了这个代码(你的修改,下面修改的细节)

    private void InitializeInterpreter()
    {
        InterProc.StartInfo.UseShellExecute = false;
        InterProc.StartInfo.FileName = "Echoer.exe";
        InterProc.StartInfo.RedirectStandardInput = true;
        InterProc.StartInfo.RedirectStandardOutput = true;
        InterProc.StartInfo.RedirectStandardError = true;
        InterProc.StartInfo.CreateNoWindow = true;
        InterProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
        InterProc.OutputDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);

        bool started = InterProc.Start();

        InterProc.BeginOutputReadLine();

    }

    private void AppendTextInBox(TextBox box, string text)
    {
        if (this.InvokeRequired)
        {
            this.Invoke((Action<TextBox, string>)AppendTextInBox, OutputTextBox, text);
        }
        else
        {
            box.Text += text;
        }
    }

    private void InterProcOutputHandler(object sendingProcess, DataReceivedEventArgs outLine)
    {
        AppendTextInBox(OutputTextBox, outLine.Data + Environment.NewLine);
    }

    private void Enterbutton_Click(object sender, EventArgs e)
    {
        InterProc.StandardInput.WriteLine(CommandTextBox.Text);
    }
Run Code Online (Sandbox Code Playgroud)

因此,我将BeginOutputReadLine移动到进程启动后.这确保它实际上只被调用一次.我还做了一个清理线程调用所需的调用.希望这对你有用.


Jad*_*ias 5

我发现的最佳解决方案是:

private void Redirect(StreamReader input, TextBox output)
{
    new Thread(a =>
    {
        var buffer = new char[1];
        while (input.Read(buffer, 0, 1) > 0)
        {
            output.Dispatcher.Invoke(new Action(delegate
            {
                output.Text += new string(buffer);
            }));
        };
    }).Start();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    process = new Process
    {
        StartInfo = new ProcessStartInfo
        {
            CreateNoWindow = true,
            FileName = "app.exe",
            RedirectStandardError = true,
            RedirectStandardOutput = true,
            UseShellExecute = false,
        }
    };
    if (process.Start())
    {
        Redirect(process.StandardError, textBox1);
        Redirect(process.StandardOutput, textBox1);
    }
}
Run Code Online (Sandbox Code Playgroud)