2010-02-23 120 views
1

我已經編寫了一個捕獲並執行命令行Python腳本的簡單程序,但有一個問題。傳遞給Python輸入函數的文本不會寫入我的程序,儘管我的程序捕獲了stdout。在標準輸出中沒有捕獲到某些Python命令

例如: 的Python腳本:

import sys 

print("Hello, World!") 
x = input("Please enter a number: ") 
print(x) 

print("This work?") 

還會寫 「你好,世界!」然後停下來。當我通過一個數字時,它會繼續寫下「請輸入一個數字:3」。到底是怎麼回事?任何解決方案我的C#如下:

public partial class PyCon : Window 
{ 
     public string strPythonPath; 
     public string strFile; 
     public string strArguments; 
     private StreamWriter sw; 

     public PyCon(string pythonpath, string file, string args) 
     { 
      strPythonPath = pythonpath; 
      strFile = file; 
      strArguments = args; 

      InitializeComponent(); 

      Process p = new Process(); 

      p.StartInfo.FileName = strPythonPath; 
      p.StartInfo.Arguments = "\"" + strFile + "\" " + strArguments; 

      p.StartInfo.UseShellExecute = false; 
      p.StartInfo.CreateNoWindow = true; 

      p.StartInfo.RedirectStandardInput = true; 
      p.StartInfo.RedirectStandardOutput = true; 
      p.StartInfo.RedirectStandardError = true; 

      p.OutputDataReceived += new DataReceivedEventHandler(p_OutputDataReceived); 
      p.ErrorDataReceived += new DataReceivedEventHandler(p_ErrorDataReceived); 

      p.Start(); 
      p.BeginOutputReadLine(); 
      p.BeginErrorReadLine(); 
      sw = p.StandardInput; 
     } 

     private void p_OutputDataReceived(object sendingProcess, DataReceivedEventArgs received) { 
      if (!String.IsNullOrEmpty(received.Data)) { 
       AppendConsole(received.Data); 
      } 
     } 

     private void p_ErrorDataReceived(object sendingProcess, DataReceivedEventArgs received) { 
      if (!String.IsNullOrEmpty(received.Data)) { 
       AppendConsole(received.Data); 
      } 
     } 

     private void AppendConsole(string message) { 
      if (!txtConsole.Dispatcher.CheckAccess()) { 
       txtConsole.Dispatcher.Invoke(DispatcherPriority.Normal, (System.Windows.Forms.MethodInvoker)delegate() { txtConsole.AppendText(message + "\n"); }); 
      } else { 
       //Format text 
       message = message.Replace("\n", Environment.NewLine); 

       txtConsole.AppendText(message + "\n"); 
      } 
     } 

     private void txtInput_KeyUp(object sender, KeyEventArgs e) { 
      if (e.Key != Key.Enter) return; 

      sw.WriteLine(txtInput.Text); 

      txtInput.Text = ""; 


     } 
    } 

編輯:大量的研究後,並從該線程的幫助,我得出的結論是,問題是用Python的輸入命令不調用C#DataReceivedEventHandler。除了腳本更改外,可能還沒有解決方案。如果是這種情況,我會做出答案,包含所接受的更改。感謝您的幫助,夥計們!

回答

1

像Python I/O這樣的氣味是行緩衝的,即等待CRLF,然後一次發送整行。您可以嘗試打開該關閉(蟒蛇-u myscript.py,或設置PYTHONUNBUFFERED環境變量)與這樣的事情或解決它:

print("Hello, World!") 
print("Please enter a number: ") 
x = input() 
print(x) 
+0

該腳本的解決方法是偉大的。它糾正了這個問題,但並不理想。 設置PYTHONUNBUFFERED或使用-u運行腳本似乎無法解決問題。 – 2010-02-23 22:25:28

1

這很難說,因爲我使用蟒蛇2.6和您似乎使用3.x中,我也沒有在C#編程很長一段時間,但我的猜測是,這條線:

sw.WriteLine(txtInput.Text); 

正在發送「3」加一個窗口換行字符。

嘗試:

sw.Write(txtInput.Text + "\n") 
sw.Flush() 

這將只發送一個正常的newline,而不是一個窗口回車這可能是問題。在處理像這樣複雜的流通信時,請確保您總是Flush!

還有一件事,確保你可以在命令提示符下重定向它。往往程序員試圖在同一時間做的一切,並卡住:

./stdintest.py < input.txt 

如果沒有在那裏工作,它不會在C#中工作。祝你好運

+0

需要注意的是,如果我在input.txt中進行操作,而不是放置正常的換行符,則在3之後放置一個^ M(windows字符),python 2.6會在解析時拋出異常「意外的EOF」。 python 3.x – manifest 2010-02-23 22:27:51

+0

這可能也可能不是這種情況刷新StreamWriter絕對是一個很好的調用。然而,換行符處理本質上與我相反的問題。輸入的帖子很好,但傳入Python輸入命令的字符串不會顯示在我的捕獲數據中。所以運行該程序就像這樣: Hello,World! 3 [< - 我輸入這個,它被髮布到StreamWriter] 請輸入一個數字:3 這項工作? 我認爲crazyscot正在吠叫正確的樹。 – 2010-02-24 02:28:59

+0

我切換到版本2.6。我看到你指的錯誤。它在3.1中似乎不是問題。 – 2010-02-24 07:01:57