2009-09-07 3 views
32

私はffmpegを次のように実行します:System.Diagnostics.Processの出力を取得する方法?

System.Diagnostics.Process p = new System.Diagnostics.Process(); 
p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); 
p.Start(); 
p.WaitForExit(); 

...しかし、問題は、ffmpegのコンソールがポップアップしてすぐに消えてしまい、フィードバックが得られないということです。プロセスが正しく実行されたかどうかはわかりません。

  • コンソールで が表示された内容を取得する

    答えて

    48

    をされて表示されたC#何に取得開か滞在するコンソールに知らせます標準出力ストリームをキャプチャします。

    p.StartInfo.RedirectStandardOutput = true; 
    p.StartInfo.UseShellExecute = false; 
    // instead of p.WaitForExit(), do 
    string q = ""; 
    while (! p.HasExited) { 
        q += p.StandardOutput.ReadToEnd(); 
    } 
    

    また、StandardErrorと同様の操作が必要な場合もあります。その後、あなたが望むことをqとすることができます。

    私はジョンスキートが指摘したように、それは次のように文字列の連結を使用するスマート性能面ではありませんone of my questions

    に発見されたとしてそれは、少し気難しいです。あなたの代わりに使うべきStringBuilder

    p.StartInfo.RedirectStandardOutput = true; 
    p.StartInfo.UseShellExecute = false; 
    // instead of p.WaitForExit(), do 
    StringBuilder q = new StringBuilder(); 
    while (! p.HasExited) { 
        q.Append(p.StandardOutput.ReadToEnd()); 
    } 
    string r = q.ToString(); 
    
    +4

    右基本的なものに沸きます私はそのような文字列を構築することをお勧めしません。StringBuilderを使用してください: –

    +0

    ありがとう、それは今すぐそれを試してみようとしています – marcgg

    +1

    実際にはエラーがあります:StandardOutはリダイレクトされていないか、プロセスはまだ開始されていません。私は何が起こっているのか把握しようとしている – marcgg

    3

    私はこの質問が古いですけど、私はとにかくそれに追加します。

    コマンドラインプロセスの出力を表示し、コンソールウィンドウからプロセスを起動するだけであれば、標準入力をリダイレクトする必要があります(はい、間違っているとわかりますが、作品)。だから、

    System.Diagnostics.Process p = new System.Diagnostics.Process(); 
    p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); 
    p.UseShellExecute = false; 
    p.RedirectStandardInput = true; 
    p.Start(); 
    p.WaitForExit(); 
    

    はうまくやるだろう。

    +0

    あなたはそれをあまり追加しませんでした。これはすでに受け入れられた答えに言及されているからです。 –

    +0

    いいえ、それはありませんでした。 –

    +16

    私は酔っていましたか、Michael Vasquez氏の名前ですか、 –

    4

    ffmpegに直接関連するより具体的な答えについては、 "-report"コマンドをffmpegに渡すと、プロセスの表示で述べたように、カレントディレクトリにログがダンプされます。

    ‘-report’

    Dump full command line and console output to a file named program-YYYYMMDD-HHMMSS.log in the current directory. This file can be useful for bug reports. It also implies -loglevel verbose.

    Note: setting the environment variable FFREPORT to any value has the same effect.

    FFMpeg Documentation

    17

    ルーカスの回答には競合があります:プロセスがすぐに終了すると、出力が残っていてもwhileループが残されます(または入力されません)。それを防ぐには、別のReadToEndに、のプロセスを終了してから行う必要があります。

    は(process.HasExitedフラグがtrueになると私の答えの旧バージョンと比較して、私はもはやWaitForExitの必要性を見ることができることに注意していないので、これは、:)

    using (var process = Process.Start(startInfo)) 
    { 
        var standardOutput = new StringBuilder(); 
    
        // read chunk-wise while process is running. 
        while (!process.HasExited) 
        { 
         standardOutput.Append(process.StandardOutput.ReadToEnd()); 
        } 
    
        // make sure not to miss out on any remaindings. 
        standardOutput.Append(process.StandardOutput.ReadToEnd()); 
    
        // ... 
    } 
    
    +0

    最初の例ではデッドロック状況が発生すると思います。プロセスがあまりにも多くの出力を書き込むと、より多くの出力を書き込む機会を待ってブロックされます。これは、特定のしきい値以下の出力に対しては発生しません。ブロックすると永遠にぶら下げられます。 [終了まで] – Cameron

    +0

    @Cameron - 私は答えを更新し、最初のコードスニペットを削除しました。さらに、2番目のスニペットでは、もうWaitToExitの必要がないことがわかりました。whileループが残っていると、プロセスが終了したことを意味します。しかし、私はあなたの主張についてはわかりません。つまり、プロセスの出力に興味がない状況であっても、コード内でwhile-ReadToEnd構造体を追加しなければならない場合は、Process.Startを使用してプロセスを開始する必要があります。プロセスはまだ "空き領域"を待っているわけではありません。 – chiccodoro

    +0

    投稿後に私の主張を確認しました。それを確認して見てください。 – Cameron

    関連する問題