我正在尝试使用标准输入和扩展来控制C#中的python会话。输出
启动Python进程后,我希望继续向它发送命令并将输出接收到我的WinForms文本框。
尝试了很多SO答案和MSDN之后,有关为什么DataReceivedEvent
处理程序未被调用的任何建议?完整代码如下:
请注意,要从Python生成Newline,请在命令文本import os;print os.linesep
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private static Process InterProc;
public Form1()
{
InitializeComponent();
InterProc = new Process();
InitializeInterpreter();
}
private void InitializeInterpreter()
{
InterProc.StartInfo.UseShellExecute = false;
InterProc.StartInfo.FileName = @"C:\Python27\python.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);
}
}
}
答案 0 :(得分:1)
这可能对上面的解决方案不起作用的其他人有所帮助。 我遇到了完全相同的问题,并且一直在苦苦挣扎,最终找到了这个问题和答案。
对我来说,通过StdError
的{{1}}被触发以进行错误输出,而只是通过ErrorDataReceived
的{{1}}未被触发。
我在Linux(Raspberry Pi)上运行dotnet core,但是在Windows上运行它也遇到了同样的问题。
我的代码与vijiboy的答案基本相同,因此我在Python中添加了Stdout
选项,但没什么区别!但这启发了我仔细研究发现它的Python选项:
-u:强制stdout和stderr流不被缓冲; 此选项对stdin无效;也PYTHONUNBUFFERED = x
因此在调用Python时添加-u(删除-i)解决了该问题,最后触发了OutputDataReceived
!
答案 1 :(得分:0)
这个答案适用于那些在这里登陆的人,他们希望在SO上有许多答案。
最终与python会话交互的代码如下:
注1:使用&#39; -i&#39;调用Python论点。 (请参阅下面的流程参数-i
)
注2:尝试从std错误冻结(Process.StandardError.ReadToEnd()
)进行同步读取。因此std输出和错误流都需要通过处理程序回调(请参阅下面的InterProcOutputHandler
)
using System;
using System.Diagnostics;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private static Process InterProc;
public Form1()
{
InitializeComponent();
InterProc = new Process();
InitializeInterpreter();
}
private void InitializeInterpreter()
{
InterProc.StartInfo.FileName = @"C:\Python27\python.exe";
InterProc.StartInfo.Arguments = @"-i"; // drops python into interactive mode after executing script if passed any
InterProc.StartInfo.UseShellExecute = false;
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);
InterProc.ErrorDataReceived += new DataReceivedEventHandler(InterProcOutputHandler);
bool started = InterProc.Start();
InterProc.BeginOutputReadLine();
InterProc.BeginErrorReadLine();
}
private void AppendTextInBox(TextBox box, string text)
{
if (InvokeRequired)
{
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);
}
}
}