2010-03-04 39 views
4

我很抱歉如果這是一個重複的問題,我搜索了一下,找不到任何類似的東西 - 我有一個Python庫,通過套接字連接到我的C#應用​​程序允許簡單的Python腳本編寫(由於幾個原因,IronPython目前不是一種選擇)。我想創建一個基本上是Python解釋器的圖形前端的Windows窗體控件,以便用戶可以運行解釋器而不必打開單獨的控制檯窗口。將Python標準輸入/輸出重定向到C#表單應用程序

我附上了一個簡單的演示,說明了我在下面嘗試過的內容,但是我一直無法使其工作。 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; 
    } 

} 

回答

15

在跨越這種情況下,任何人都跌倒,我想通了這個問題 - 在默認情況下,如果它檢測到一個TTY設備Python解釋器唯一進入交互模式連接到標準輸入(通常只有當程序從控制檯運行時纔是如此)。爲了重定向標準IO流,您必須將ProcessStartInfo中的UseShellExecute設置爲false,這會導致解釋器認爲沒有TTY連接,這意味着它立即退出,因爲它沒有任何關係。

解決方案是使用「-i」命令行參數運行Python解釋器,這將強制解釋器進入交互模式,無論是否有TTY連接到標準輸入。這使得上述示例正常工作。

+0

ProcessStartInfo psi = new ProcessStartInfo(PytonPath,String.Format(「 - i {0}」,scriptFileInfo.Name)); – Kyordhel

+0

幹得好的男人。謝謝 –

0

寫在單獨的線程:

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

我嘗試過使用各種不同的_pythonProc.StandardOutput.Read方法,但它們都會立即封鎖並永遠不會返回。似乎沒有任何內容實際上發佈到標準輸出流。 –

相關問題