2009-05-03 121 views
3

我試圖讓PHP解析器運行一個頁面,然後將結果返回給我的服務器,但是當我通過我的代碼運行命令時,它不返回任何內容。我知道該命令是正確的,因爲如果我用相同的路徑手動運行它,它工作正常。我的繼承人代碼:C#:運行shell命令的問題

var p = new Process 
{ 
     StartInfo = new ProcessStartInfo("C:\\xampp\\php\\php.exe", path) 
     { 
      RedirectStandardOutput = true, 
      RedirectStandardError = true, 
      UseShellExecute = false, 
      CreateNoWindow = true 
     } 
}; 
var output = new StringWriter(); 
var error = new StringWriter(); 
p.OutputDataReceived += (sender, args) => output.WriteLine(args.Data); 
p.ErrorDataReceived += (sender, args) => error.WriteLine(args.Data); 
p.Start(); 
p.BeginOutputReadLine(); 
p.BeginErrorReadLine(); 
p.WaitForExit(); 
if (p.ExitCode != 0) 
{ 
     throw new Exception(string.Format(
      "PHP failed with the following output:{0}{1}", 
     /* {0} */ Environment.NewLine, 
     /* {1} */ error.GetStringBuilder().ToString())); 
} 
var res = output.GetStringBuilder().ToString(); 
Console.WriteLine(res); 

編輯: 有了這個當前的代碼,它拋出在沒有輸出的代碼除外。

+0

也許如果您詳細解釋一下你正在努力去做,我們可以找到更好的解決方案。 – 2009-05-03 14:27:17

+0

當你說「它什麼都沒有返回」時,你是說res在進程運行後是空的,還是永遠不會退步? – 2009-05-03 19:33:47

+0

對不起,返回空字符串 – 2009-05-03 19:52:32

回答

5

設置WorkingDirectory路徑

var p = new Process 
      { 
       StartInfo = new ProcessStartInfo("php", path) 
       { 
        RedirectStandardOutput = true, 
        RedirectStandardError = true, 
        UseShellExecute = false, 
        CreateNoWindow = true, 
        WorkingDirectory = workingDir 
       } 
      }; 
5

問題是您在程序結束前正在讀取輸出。您需要等待程序退出來處理輸出。否則,您將在解析完成之前處理輸出。添加以下行。

p.Start(); 
p.WaitForExit(); // New line 

編輯 OP說,他們仍然有問題。

嘗試刪除命令的CMD部分。只需直接運行PHP命令。允許創建一個用於調試目的的窗口也許是有益的,因此您可以看到運行該命令可能出現的任何錯誤。

+0

你有我,+1 :) – 2009-05-03 14:27:15

1

ReadToEnd()只是讀取流在當時的整個內容。鑑於您在Start()之後立即打電話,該流可能爲空。你有幾個選項

  • 呼叫ReadLine()代替,但這隻會讀取一行
  • p.WaitForExit()然後調用ReadToEnd(),但我不能肯定這保持流開放。如果是這樣,那麼這是你最好的選擇。
1

您需要添加p.WaitForExit();在p.Start()之後;否則當您嘗試讀取輸出時,輸出未準備好。

0

是否有你通過cmd運行php的原因?你不能直接執行它嗎?

我的經驗是,通過.NET執行進程是執行另一個進程的最糟糕的方式。 fork()在unix下非常好。我有很多問題,我的建議是,你考慮看看Process.BeginOutputReadLine()並在你的閱讀中去異步路線。 ReadToEnd和ReadToLine可以無限期地掛起,特別是如果你有很長的輸出來捕獲。

我會貼一個例子,但它相當長。

2

最穩健的方式來調用過程並捕獲它的輸出或錯誤會嘗試一下以下的方法:

var p = new Process { 
    StartInfo = new ProcessStartInfo("php", path) { 
     RedirectStandardOutput = true, 
     RedirectStandardError = true, 
     UseShellExecute = false, 
     CreateNoWindow = true 
    } 
}; 
var output = new StringWriter(); 
var error = new StringWriter(); 
p.OutputDataReceived += (sender, args) => output.WriteLine(args.Data); 
p.ErrorDataReceived += (sender, args) => error.WriteLine(args.Data); 
p.Start(); 
p.BeginOutputReadLine(); 
p.BeginErrorReadLine(); 
p.WaitForExit(); 
if (p.ExitCode != 0) { 
    throw new Exception(string.Format(
     "PHP failed with the following output:{0}{1}", 
     /* {0} */ Environment.NewLine, 
     /* {1} */ error.GetStringBuilder().ToString())); 
} 
var res = output.GetStringBuilder().ToString(); 
Console.WriteLine(res);