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();
}
}
}
答案 0 :(得分:1)
Process.StandardOutput
throws an InvalidOperationException
when
The StandardOutput stream has been opened for asynchronous read operations with BeginOutputReadLine.
So you must either
StandardOutput
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 :
- Set UseShellExecute to false.
- Set RedirectStandardError to true.
- Add your event handler to the ErrorDataReceived event. The event handler must match the System.Diagnostics.DataReceivedEventHandler delegate signature.
- Start the Process.
- 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:
The ProcessStartInfo.RedirectStandardError
property is false
.
An asynchronous read operation is already in progress on the StandardError
stream.
The StandardError
stream has been used by a synchronous read operation
From MSDN
In your case try to set true
for
myProcess.RedirectStandardError = true;