将Python标准输入/输出重定向到C#表单应用程序

时间:2010-03-04 15:55:01

标签: c# python redirect stdout stdin

我很抱歉,如果这是一个重复的问题,我搜索了一下,找不到类似的东西 - 我有一个Python库,通过套接字连接到我的C#应用​​程序,以便允许简单的Python脚本(IronPython不是现在有一个选择,原因有两个)。我想创建一个Windows窗体控件,它基本上是Python解释器的图形前端,这样用户就可以运行解释器而无需打开单独的控制台窗口。

我附上了一个关于我到目前为止尝试过的简单演示,但是我无法让它工作。永远不会调用DataReceived事件处理程序,当我尝试写入标准输入时,解释器中没有任何操作。有没有人对我做错了什么有反馈,或者这是否可能?

public partial class Form1 : Form
{

    Process _pythonProc;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ProcessStartInfo psi = new ProcessStartInfo()
        {
            FileName = @"C:\Python26\Python.exe",
            CreateNoWindow = true,
            UseShellExecute = false,
            RedirectStandardInput = true,
            RedirectStandardOutput = true,
            RedirectStandardError = true
        };
        _pythonProc = new Process();
        _pythonProc.OutputDataReceived += OutputDataReceived;
        _pythonProc.ErrorDataReceived += ErrorDataReceived;
        _pythonProc.StartInfo = psi;
        _pythonProc.Start();
    }

    private void cmdExecute_Click(object sender, EventArgs e)
    {
        string cmd = textInput.Text;
        _pythonProc.StandardInput.WriteLine(cmd);
        _pythonProc.StandardInput.Flush();
        textInput.Text = string.Empty;
    }

    private void Form1_FormClosed(object sender, FormClosedEventArgs e)
    {
        if (!_pythonProc.HasExited)
            _pythonProc.Kill();
    }

    private void OutputDataReceived(object sender, DataReceivedEventArgs args)
    {
        textOutput.Text += args.Data;
    }

    private void ErrorDataReceived(object sender, DataReceivedEventArgs args)
    {
        textOutput.Text += args.Data;
    }

}

2 个答案:

答案 0 :(得分:15)

如果其他人偶然发现了这个问题,我想出了问题 - 默认情况下,Python解释器只有在检测到TTY设备连接到标准输入时才进入交互模式(通常只有在程序运行时才会出现)从控制台)。为了重定向标准IO流,您必须将ProcessStartInfo中的UseShellExecute设置为false,这会导致解释器认为没有连接TTY,这意味着它会立即退出,因为它无关。

解决方案是使用“-i”命令行参数运行Python解释器,这会强制解释器进入交互模式,无论是否有连接到标准的TTY。这使得上面的示例正常工作。 / p>

答案 1 :(得分:0)

写在单独的帖子中:

while(cond)
{
   string s = _pythonProc.StandardOutput.ReadLine();
   textOutput.Invoke( () => { textOutput.Text += s; } );
}