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

发布于 2024-08-24 01:04:55 字数 1736 浏览 8 评论 0原文

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

}

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.

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:\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;
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冷默言语 2024-08-31 01:04:56

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

解决方案是使用“-i”命令行参数运行Python解释器,这会强制解释器进入交互模式,无论是否有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.

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.

南烟 2024-08-31 01:04:56

在单独的线程中写入:

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

write in separate thread:

while(cond)
{
   string s = _pythonProc.StandardOutput.ReadLine();
   textOutput.Invoke( () => { textOutput.Text += s; } );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文