Error while getting output of a process in real time

时间:2016-07-11 19:21:05

标签: c#

I am trying to get the output of a process in real time and at the same time save it to a variable,i tried the following looking at other stackoverflow questions C# Show output of Process in real time ,however I get an InvalidOperationException error at line StreamReader myStreamReader = myProcess.StandardOutput,what am I missing?how to fix it?

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

    }

}

3 个答案:

答案 0 :(得分:1)

Process.StandardOutput throws an InvalidOperationException when

The StandardOutput stream has been opened for asynchronous read operations with BeginOutputReadLine.

So you must either

  1. Read from StandardOutput
  2. Handle OutputDataReceivedEvent and call BeginOutputReadLine()

but not both.


For example, collect the output while printing each line to the console:

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

答案 1 :(得分:0)

Set RedirectStandardOutput to true in order to read from the standard output.

Set RedirectStandardError to true in order to read from the standard error output.

In further details, here are the instructions that the documentation gives:

Follow these steps to perform asynchronous read operations on StandardError for a Process :

  1. Set UseShellExecute to false.
  2. Set RedirectStandardError to true.
  3. Add your event handler to the ErrorDataReceived event. The event handler must match the System.Diagnostics.DataReceivedEventHandler delegate signature.
  4. Start the Process.
  5. Call BeginErrorReadLine for the Process. This call starts asynchronous read operations on StandardError.

When asynchronous read operations start, the event handler is called each time the associated Process writes a line of text to its StandardError stream.

You can cancel an asynchronous read operation by calling CancelErrorRead. The read operation can be canceled by the caller or by the event handler. After canceling, you can call BeginErrorReadLine again to resume asynchronous read operations.

So before starting your process, you'll want to set:

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

I imagine you'll want to do the same thing for Standard Output.

答案 2 :(得分:0)

Condition to InvalidOperationException in BeginErrorReadLine method:

From MSDN

In your case try to set true for

myProcess.RedirectStandardError = true;