Reputation: 114
I want to get output of the cmd result in a string
void getDevices()
{
Process p = new Process();
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = @"C:\Users\mehmetcan\Desktop\adt-bundle-windows-x86-20130917\sdk\platform-tools\adb.exe";
proc.Arguments = @"devices";
Process.Start(proc);
String output = p.StandardOutput.ReadToEnd();
}
Error: An unhandled exception of type 'System.InvalidOperationException' occurred in System.dll
Upvotes: 3
Views: 1380
Reputation: 224
You have to give your process a ProcessStartInfo that tells it you're going to be reading the output.
Here is an example:
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = @"C:\Users\mehmetcan\Desktop\adt-bundle-windows-x86-20130917\sdk\platform-tools\adb.exe";
startinfo.Arguments = @"devices";
startinfo.RedirectStandardOutput = true;
startinfo.RedirectStandardError = true;
// Note: declare process as a variable in the class as it needs to be used in the event handlers
process = new Process();
process.StartInfo = startinfo;
process.OutputDataReceived += process_DataReceived;
process.ErrorDataReceived += process_DataReceived;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
And then the event hander that receives the data (this is called each time the process outputs something):
private void process_DataReceived(object sender, DataReceivedEventArgs e)
{
// null data means we've received everything
if (e.Data == null) {
process.CancelOutputRead();
process.CancelErrorRead();
return;
}
// e.Data is the string with the output from the process
Console.Write(e.Data);
}
Note that process_DataReceived
is called whenever the process outputs something, if what you need is to get the complete output, then you can do this:
process_output = ""; // reset output before starting the process
ProcessStartInfo startinfo = new ProcessStartInfo();
startinfo.FileName = @"C:\Users\mehmetcan\Desktop\adt-bundle-windows-x86-20130917\sdk\platform-tools\adb.exe";
startinfo.Arguments = @"devices";
startinfo.RedirectStandardOutput = true;
startinfo.RedirectStandardError = true;
Process process = new Process();
process.StartInfo = startinfo;
process.OutputDataReceived += process_DataReceived;
process.ErrorDataReceived += process_DataReceived;
process.Start();
process.BeginOutputReadLine();
process.BeginErrorReadLine();
// check end of answer if you need to wait for the process to terminate
Declare a string variable that is available to both process_DataReceived
and to process_Exited
, for example a variable in the class that contains the methods:
string process_output; // will accumulate the output of the process
And then the event handlers:
private void process_DataReceived(object sender, DataReceivedEventArgs e)
{
// null data means we've received everything
if (e.Data == null) {
process.CancelOutputRead();
process.CancelErrorRead();
// do something with the output:
Console.Write(process_output);
return;
}
// append the output to the accumulator
process_output += e.Data;
}
After the process exits, you can still receive output data, therefore if you need to wait for the process to finish, you can add a flag (a boolean) and set it to false only when you receive null data in process_DataReceived
. You can only be sure you've received all of the output from the process when that happens.
If you have to access a UI element from process_DataReceived
you can do so by using it's dispatcher.
Here is an example:
private void process_DataReceived(object sender, DataReceivedEventArgs e)
{
// null data means we've received everything
if (e.Data == null) {
process.CancelOutputRead();
process.CancelErrorRead();
// with WPF:
mylabel.Dispatcher.Invoke(new Action(() => {
mylabel.Content = process_output;
}));
// with WinForms
mylabel.Invoke((MethodInvoker) (() =>
{
mylabel.Text = process_output;
}));
return;
}
// append the output to the accumulator
process_output += e.Data;
}
Upvotes: 4
Reputation: 172378
How about trying like this:-
public static void Main()
{
ProcessStartInfo proc = new ProcessStartInfo();
proc.FileName = @"C:\Users\mehmetcan\Desktop\adt-bundle-windows-x86-20130917\sdk\platform-tools\adb.exe";
proc.Arguments = @"devices";
Process p = Process.Start(proc);
p.OutputDataReceived += (sender, e) => Console.WriteLine(e.Data);
p.BeginOutputReadLine();
p.Start();
p.WaitForExit();
Thread.Sleep(5000);
}
Also check Process.OutputDataReceived and Process.BeginOutputReadLine
Upvotes: 1