【问题标题】:Redirect Python standard input/output to C# forms application将 Python 标准输入/输出重定向到 C# 表单应用程序
【发布时间】:2011-01-23 18:01:58
【问题描述】:

如果这是一个重复的问题,我深表歉意,我搜索了一下,找不到任何类似的东西 - 我有一个 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;
    }

}

【问题讨论】:

    标签: c# python redirect stdout stdin


    【解决方案1】:

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

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

    【讨论】:

    • ProcessStartInfo psi = new ProcessStartInfo(PytonPath, String.Format("-i {0}", scriptFileInfo.Name));
    【解决方案2】:

    写在单独的线程中:

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

    【讨论】:

    • 我尝试了各种不同的 _pythonProc.StandardOutput.Read 方法,但它们都立即阻塞并且永远不会返回。似乎实际上没有任何内容被发布到标准输出流。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-26
    • 1970-01-01
    • 1970-01-01
    • 2011-12-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多