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

8 投票
2 回答
5193 浏览
提问于 2025-04-15 20:01

抱歉如果这个问题重复了,我搜索了一下没找到类似的内容。我有一个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 个回答

1

在单独的线程中写入:

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

如果有人遇到这个问题,我找到了原因——默认情况下,Python解释器只有在检测到标准输入连接了一个TTY设备时才会进入交互模式(这通常只有在从控制台运行程序时才会发生)。为了重定向标准输入输出流,你需要把ProcessStartInfo中的UseShellExecute设置为false,这样解释器就会认为没有TTY连接,因此它会立刻退出,因为没有事情可做。

解决办法是用“-i”这个命令行参数来运行Python解释器,这样无论标准输入是否连接了TTY,它都会强制进入交互模式。这样,上面的例子就能正常工作了。

撰写回答