2009-05-03 17 views
3

PHPパーサーがページを実行して、結果をサーバーに返すようにしようとしていますが、コードでコマンドを実行すると何も返されません。私はコマンドが正しいことを知っています。なぜなら、同じパスで手動で実行するとうまく動作するからです。 HERESに私のコード:C#:シェルコマンドの実行中の問題

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); 

EDIT:この現在のコードでは 、それは何も出力しないコードで例外がスローされます。

+0

あなたは詳細に説明した場合に何私たちはより良い解決策を見つけることができました。 –

+0

「何も返さない」と言うと、プロセスが実行された後にresが空であることを意味するのですか、決してretutrnsしないということですか? –

+0

申し訳ありませんが、空の文字列を返します –

答えて

5

設定WORKINGDIRECTORYパスたぶん

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

p.Start()に「システムは指定されたファイルを見つけることができません」というメッセージを表示して例外をスローします。 –

+0

エラーが発生しましたか?たとえば、StartInfo = new ProcessStartInfo( "C:\\ xampp \\ php \\ php.exe"、パス) –

+0

これはうまくいきました。ありがとう! –

5

問題は、プログラムが終了する前に出力を読み取っていることです。出力を処理するには、プログラムの終了を待つ必要があります。それ以外の場合は、解析が完了する前に出力を処理します。次の行を追加します。

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

EDIT OP彼らはまだ問題を抱えていると述べました。

コマンドのCMD部分を削除してみます。 PHPコマンドを直接実行してください。また、デバッグ用のウィンドウを作成できるようにすると、コマンドを実行する際に発生する可能性のあるエラーを確認することができます。

+0

あなたは私を持っています+1: –

+0

hrm、私はこれを試しましたが、私はまだ同じ問題があるようです –

+0

Hrm、私はcmdの部分を削除しようとしましたが、それは私に "ファイル名、ディレクトリ名、またはボリュームラベルの構文が正しくありません " –

1

ReadToEnd()は、その時点でストリームの内容全体を読み込むだけです。 Start()の直後にこれを呼び出すと、ストリームはおそらく空です。あなたはオプション

  • 代わりにコールReadLine()のカップルを持っているが、これは一行だけ
  • p.WaitForExit()が、その後ReadToEnd()を呼び出して読みますが、私は、これは、オープンストリームを保持し、特定していません。そうであれば、これが最善の選択肢です。
1

p.WaitForExit();を追加する必要があります。 p.Start()の後に。それ以外の場合は、読み込みしようとすると出力が準備できません。

0

cmdを使用してphpを実行している理由はありますか?あなたはそれを直接実行できませんか?

.NETを使用してプロセスを実行することは、別のプロセスを実行する最悪の方法です。 UNIX上のfork()は驚くほど優れています。私は非常に多くの問題を抱えていたので、私の助言はあなたですSTRONGLYProcess.BeginOutputReadLine()を見て、あなたの読書に非同期ルートに行くことを検討してください。 ReadToEndとReadToLineは、キャプチャする時間が長い場合に特に無期限にハングする可能性があります。

私は例を貼り付けますが、かなり長めです。

+0

私はこれを試してみたいと思いますが、私の意見では、MSDNの例はかなり悪いです。 –

+0

これを包むために書いたクラスは仕事中です。 途中で、gistは、Process.OutputDataReceivedを、文字列を成長するプライベートクラス文字列に連結するクラス静的メソッドに設定するクラスです。プロセスの実行が終了すると、パブリックプロパティを介して文字列にアクセスします。 stderrと同じことをstdoutと同じように行うことができます。効果的には、それはプロセスがすべきことです。 :) –

+0

私はそれを試みましたが、どちらもうまくいきませんでした。 –

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); 
+0

OKこれを試してみましたが、コマンド部分を編集しなければなりませんでした。それを "cmd"、 "/ c php" +パスに変更しました。 「php」が内部または外部のコマンド、 操作可能なプログラムまたはバッチファイルとして認識されません。しかし、これに関する奇妙なことは、私がコマンドプロンプトを開いて実行すると、phpコマンドが機能するということです。 –

+0

ProcessStartupInfoコンストラクタの最初の引数として、実行可能ファイルの絶対パスを絶対パスで指定してみてください。 "cmd"を使用することは過剰です。 –

+0

私はこれを試して、空白の出力で例外をスローしました。 –

関連する問題