将 Python 标准输入/输出重定向到 C# 表单应用程序 [英] Redirect Python standard input/output to C# forms application

查看:22
本文介绍了将 Python 标准输入/输出重定向到 C# 表单应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I apologize if this is a duplicate question, I searched a bit and couldn't find anything similar - I have a Python library that connects to my C# application via a socket in order to allow simple Python scripting (IronPython isn't an option right now for a couple of reasons). I would like to create a Windows Forms control that would be basically a graphical front-end for the Python interpreter, so that the user could run the interpreter without having to have a separate console window open.

我在下面附上了迄今为止我尝试过的简单演示,但我一直无法让它工作.DataReceived 事件处理程序永远不会被调用,当我尝试写入标准输入时,解释器中没有任何反应.有没有人对我做错了什么有任何反馈,或者这是否可能?

I attached a simple demo of what I've tried so far below, but I haven't been able to get it to work. The DataReceived event handlers are never called, and when I try to write to the standard input nothing happens in the interpreter. Does anyone have any feedback about what I'm doing wrong, or if this is even possible?

public partial class Form1 : Form
{

    Process _pythonProc;

    public Form1()
    {
        InitializeComponent();
    }

    private void Form1_Load(object sender, EventArgs e)
    {
        ProcessStartInfo psi = new ProcessStartInfo()
        {
            FileName = @"C:Python26Python.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;
    }

}

推荐答案

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

In case anyone else stumbles across this, I figured out the problem - by default, the Python interpreter only enters interactive mode if it detects that a TTY device is connected to standard input (which is normally only true if the program is run from the console). In order to redirect the standard IO streams, you have to set UseShellExecute in the ProcessStartInfo to false, which causes the interpreter to think that there is no TTY connected, meaning it immediately exits since it has nothing to do.

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

The solution is to run the Python interpreter with the "-i" command line argument, which forces the interpreter to interactive mode, regardless of whether there is a TTY connected to standard in. This makes the example above work correctly.

这篇关于将 Python 标准输入/输出重定向到 C# 表单应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆