簡體   English   中英

將Python標准輸入/輸出重定向到C#表單應用程序

[英]Redirect Python standard input/output to C# forms application

我道歉,如果這是一個重復的問題,我搜索了一下,找不到任何類似的東西 - 我有一個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;
    }

}

如果其他人偶然發現了這個問題,我想出了問題 - 默認情況下,Python解釋器只有在檢測到TTY設備連接到標准輸入時才進入交互模式(如果程序是從控制台運行的話,通常情況下都是如此) )。 為了重定向標准IO流,您必須將ProcessStartInfo中的UseShellExecute設置為false,這會導致解釋器認為沒有連接TTY,這意味着它會立即退出,因為它無關。

解決方案是使用“-i”命令行參數運行Python解釋器,這會強制解釋器進入交互模式,無論是否有連接到標准的TTY。這使得上面的示例正常工作。

寫在單獨的線程中:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM