从控制台应用程序发送输入/获取输出 (C#/WinForms)
我有一个包含 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();
}
}
有什么方法可以让它顺利运行吗?谢谢。
I have a form with 3 controls:
- A textbox for the user to enter
commands to send to a console
application, - A button to confirm the commands to
be sent and - A read-only textbox to display the
output from the application.
What I want is for the user to enter commands in the first textbox, press the button to enter and receive feedback via the second textbox.
I know how to use ProcessStartInfo.RedirectStandardOutput
but, however, the app hangs when I use StandardOutput.ReadToEnd()
.
I had a look at the asynchronous Process.BeginOutputReadLine()
but, even though my app does not hang, somehow I get no response in the textbox, it does absolutely nothing.
Here's my code:
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();
}
}
Is there any way I can have this run smoothly? Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果您想要一些交互式的内容,我可以让这段代码起作用(您的代码已修改,修改的详细信息如下)
因此,我将 BeginOutputReadLine 移至进程启动后。这确保了它实际上只被调用一次。我还执行了清理线程调用所需的调用。希望这对你有用。
If you want something interactive, I got this code to work (yours modified, details on modifications below)
So, I moved the BeginOutputReadLine to just after the process is started. That ensures it's really only called once. I also did an invoke required to clean up thread calls. Hopefully this should work for you.
我发现的最佳解决方案是:
The best solution I have found is:
我使用过类似这样的代码:
但它不是交互式的。但如果应用程序是交互式的,那么无论如何它都会需要更多的代码。
I've used code something like this:
But it's not interactive. But if the app is interactive, it'll take a lot more code anyway.
您在哪里调用
StandardOutput.ReadToEnd()
?我曾经遇到过类似的问题,因为我在StandardOutput.ReadToEnd()
之前调用了Process.WaitForExit()
。我有大量的输入,并且输出缓冲区在完成之前已满,并且我的进程被阻塞。您必须在
Process.WaitForExit()
之前调用StandardOutput.ReadToEnd()
。Where are you calling
StandardOutput.ReadToEnd()
? I once had a similar problem because I was callingProcess.WaitForExit()
beforeStandardOutput.ReadToEnd()
. I had a large amount of input, and the output buffer was full before completion and my process was blocked.You must call
StandardOutput.ReadToEnd()
beforeProcess.WaitForExit()
.