2016-07-11 81 views
2

リアルタイムでプロセスの出力を取得しようとしています同時に変数に保存すると、私は他のstackoverflowの質問C# Show output of Process in real time、しかしInvalidOperationException行のエラーStreamReader myStreamReader = myProcess.StandardOutputが表示されますが、何が不足していますか?修正方法は?リアルタイムでプロセスの出力を取得中にエラーが発生しました

using System; 
using System.IO; 
using System.Diagnostics; 
using System.Text.RegularExpressions; 
namespace CallPython 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      // full path of python interpreter 
      string python = @"C:\\Python27\python.exe"; 

      // python app to call 
      string myPythonApp = @"C:\\Dropbox\script.py"; 

      // dummy parameters to send Python script 

      string m = @"\\location\\build1"; 
      string s = "emmc"; 
      string a = "3980bdd4"; 
      string ft = "60000"; 
      string at = "60000"; 
      string bt = "120000"; 


      // Create new process start info 
      ProcessStartInfo myProcessStartInfo = new ProcessStartInfo(python); 

      // make sure we can read the output from stdout 
      myProcessStartInfo.UseShellExecute = false; 
      myProcessStartInfo.RedirectStandardOutput = true; 
      myProcessStartInfo.RedirectStandardError = true; 

      // start python app with arguments 
      //myProcessStartInfo.Arguments = myPythonApp + " " + "-m" + " " + m + " " + "-s" + " " + s + " " + "-a" + " " + a + " " + "-ft" + " " + ft + " " + "-at" + " " + at + " " + "-bt" + " " + bt; 
      myProcessStartInfo.Arguments = String.Format("{0} -m {1} -s {2} -a {3} -ft {4} -at {5} -bt {6}", myPythonApp, m,s,a,ft,at,bt); 

      Process myProcess = new Process(); 
      // assign start information to the process 
      myProcess.StartInfo = myProcessStartInfo; 

      Console.WriteLine("Calling Python script with arguments {0} ,{1},{2},{3},{4},{5}", m, s,a,ft,at,bt); 
      // start the process 
      myProcess.Start(); 

      myProcess.BeginErrorReadLine(); 
      myProcess.BeginOutputReadLine(); 

      StreamReader myStreamReader = myProcess.StandardOutput; 

      string myString = myStreamReader.ReadToEnd(); 


      //Console.WriteLine(myString); 
      //Add code for parsing based on myString 

      // wait exit signal from the app we called and then close it. 
      myProcess.WaitForExit(); 
      myProcess.Close(); 
      Console.ReadLine(); 
     } 

    } 

} 
+1

をあなたも、引用された質問からのアプローチを試してみたのですか? stdoutストリームとstderrストリームをリダイレクトし、イベントハンドラをアタッチし、 'UseShellExecute'をfalseに設定しますか? – dlatikay

答えて

0

は標準出力から読み取るためにtrueRedirectStandardOutputを設定します。

RedirectStandardErrortrueを標準エラー出力から読み込むために設定します。

は、プロセスのためにはStandardErrorに非同期の読み取り操作を実行するには、次の手順を実行します:

  1. セットあるUseShellExecuteをfalseに

    は、さらに詳細には、ここでthe documentationが与える命令です。

  2. RedirectStandardErrorをtrueに設定します。
  3. イベントハンドラをErrorDataReceivedイベントに追加します。イベントハンドラは、System.Diagnostics.DataReceivedEventHandlerデリゲートシグネチャと一致する必要があります。
  4. プロセスを開始します。
  5. プロセスのBeginErrorReadLineを呼び出します。この呼び出しは、StandardErrorの非同期読み取り操作を開始します。

非同期読み取り操作が開始されると、関連するプロセスがテキスト行をStandardErrorストリームに書き込むたびにイベントハンドラが呼び出されます。

CancelErrorReadを呼び出すと、非同期読み取り操作をキャンセルできます。読み取り操作は、呼び出し元またはイベントハンドラによってキャンセルできます。キャンセル後、BeginErrorReadLineを再度呼び出して、非同期読み取り操作を再開できます。

だからあなたのプロセスを開始する前に、あなたが設定したいと思う:

myProcessStartInfo.UseShellExecute = false; 
myProcessStartInfo.RedirectStandardError = true; 
myProcessStartInfo.ErrorDataReceived += (obj, args) => { 
    // add code 
}; 

私はあなたが標準出力のために同じことをしたいと思うだろうと想像。

+0

あなたの提案に基づいて最新のコードを更新しました。今度は 'StreamReader myStreamReader = myProcess.StandardOutput;例外が発生します。 –

+0

@PythonProg:リンク先のドキュメントから:"リダイレクトされたストリームで非同期および同期読み取り操作を混在させることはできませんプロセスのリダイレクトされたストリームが非同期モードまたは同期モードのいずれかで開かれたら、そのストリーム上のそれ以降の読み取り操作はすべて同じモードでなければなりません。例えば、BeginErrorReadLineの後にStandardErrorストリームのReadLineたとえば、BeginErrorReadLineを呼び出してから、StandardOutputストリームのReadLineを呼び出すことができます。 – StriplingWarrior

+0

あなたが完全であり、より理解しやすいサンプルコードを表示できる場合 –

0

BeginErrorReadLine方法でInvalidOperationExceptionへの条件:

使用されていますが

myProcess.RedirectStandardError = true; 
+0

あなたの提案に基づいて完全なコードを更新しましたが、 'StreamReader myStreamReader = myProcess.StandardOutput; '例外が発生しました@ –

+0

@PythonProgどのような種類例外の? InvalidOperationException? 'UseShellExecute'に' false'を設定するか、削除してみてください: 'myProcess.BeginErrorReadLine(); myProcess.BeginOutputReadLine(); ' – Marusyk

+0

すべての標準出力ストリームを削除してmyStringに格納してから、私はすでに何ができるかを解析できます。私の質問では、stdoutをコンソールにリダイレクトして出力を変数に保存する方法 –

1

Process.StandardOutputためtrueを設定しようInvalidOperationExceptionとき

をスローします

BeginOutputReadLineを使用して非同期読み取り オペレーション用にStandardOutputストリームが開かれました。

だから、StandardOutput

  • から

    1. 読むにはOutputDataReceivedEventを処理していない両方BeginOutputReadLine()

    が、を呼び出す必要があります。例えば


    、コンソールにそれぞれの行を印刷しながら出力を収集:

    StreamReader reader = process.StandardOutput; 
    StringBuilder builder = new StringBuilder(); 
    
    string line; 
    while ((line = reader.ReadLine()) != null) 
    { 
        builder.AppendLine(line); 
        Console.WriteLine(line); 
    } 
    
    string allLines = builder.ToString(); 
    
  • +0

    @MegaTron - 私はすべての標準出力ストリームを削除すると 'myString'に格納され、私はすでに何ができるかを解析することができます、私の質問はどのようにコンソールにstdoutをリダイレクトし、変数 –

    +0

    @PythonProgあなたがしたいことのためにいくつかのコードを追加しました。 – piedar

    関連する問題