ProcessInfo y RedirectStandardOutput

Tengo una aplicación que llama a otro proceso en una ventana de comandos y ese proceso tiene estadísticas de actualización que salen a la ventana de la consola. Pensé que esta era una operación bastante simple, pero parece que no puedo hacer que funcione. ¿Me estoy perdiendo de algo?

string assemblyLocation = Assembly.GetExecutingAssembly().Location; Process process = new Process { ProcessStart = { RedirectStandardOutput = true, UseShellExecute = false, WindowStyle = ProcessWindowStyle.Hidden, Arguments = arg, FileName = assemblyLocation.Substring(0, assemblyLocation.LastIndexOf("\\")) + "\\ffmpeg.exe", CreateNoWindow = true } }; process.Start(); Console.WriteLine(process.StandardOutput.ReadToEnd()); process.WaitForExit(); 

Idealmente, lo que me gustaría es que a medida que el producto cambie dentro de ese proceso o los datos lleguen al lector, obtenga los eventos que se obtengan de él.

Cualquier ayuda sería genial, siento que esta es una pregunta para novatos, pero parece que falta algo.

He experimentado esto antes. A veces, la forma en que el proceso que está llamando genera la consola no es compatible con este tipo de redirección de salida. Tuve la suerte en este caso de poder modificar el proceso externo para evitar esto.

Puede intentar ejecutar su código en otro proceso que se envía a la consola y ver si funciona correctamente. A mí me parece correcto en este momento.

EDITAR:

Fui y saqué un bloque de código que he usado para hacer esto. Esto se encuentra en una aplicación WPF que redirige la salida del proceso a la ventana. Observe el enlace del evento. Como esto es WPF, tengo que invocar mi llamada para escribir los datos. Como no está preocupado por el locking, debería poder reemplazarlo simplemente por:

 Console.WriteLine(e.Data); 

¡Espero que ayude!

  private static void LaunchProcess() { Process build = new Process(); build.StartInfo.WorkingDirectory = @"dir"; build.StartInfo.Arguments = ""; build.StartInfo.FileName = "my.exe"; build.StartInfo.UseShellExecute = false; build.StartInfo.RedirectStandardOutput = true; build.StartInfo.RedirectStandardError = true; build.StartInfo.CreateNoWindow = true; build.ErrorDataReceived += build_ErrorDataReceived; build.OutputDataReceived += build_ErrorDataReceived; build.EnableRaisingEvents = true; build.Start(); build.BeginOutputReadLine(); build.BeginErrorReadLine(); build.WaitForExit(); } // write out info to the display window static void build_ErrorDataReceived(object sender, DataReceivedEventArgs e) { string strMessage = e.Data; if (richTextBox != null && !String.Empty(strMessage)) { App.Instance.Dispatcher.BeginInvoke(DispatcherPriority.Send, (ThreadStart)delegate() { Paragraph para = new Paragraph(new Run(strMessage)); para.Margin = new Thickness(0); para.Background = brushErrorBrush; box.Document.Blocks.Add(para); }); } } 

No estoy seguro exactamente de qué problema se está metiendo, pero si está buscando actuar en la salida tan pronto como se genera, intente conectar el evento OutputDataReceived del proceso. Puede especificar manejadores para recibir salida de forma asincrónica del proceso. He utilizado este enfoque con éxito.

 ProcessStartInfo info = new ProcessStartInfo(...) info.UseShellExecute = false; info.RedirectStandardOutput = true; info.RedirectStandardError = true; Process p = Process.Start(info); p.OutputDataReceived += p_OutputDataReceived; p.ErrorDataReceived += p_ErrorDataReceived; p.BeginOutputReadLine(); p.BeginErrorReadLine(); p.WaitForExit(); 

..

 void p_OutputDataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine("Received from standard out: " + e.Data); } void p_ErrorDataReceived(object sender, DataReceivedEventArgs e) { Console.WriteLine("Received from standard error: " + e.Data); } 

Vea el evento OutputDataReceived off para más información.

Usando expresiones lambda, etc.

 var info = new ProcessStartInfo(path) { RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, Verb = "runas", }; var process = new Process { EnableRaisingEvents = true, StartInfo = info }; Action actionWrite = (sender, e) => { Console.WriteLine(e.Data); }; process.ErrorDataReceived += (sender, e) => actionWrite(sender, e); process.OutputDataReceived += (sender, e) => actionWrite(sender, e); process.Start(); process.BeginOutputReadLine(); process.BeginErrorReadLine(); process.WaitForExit(); 

Curiosamente, no puede leer el resultado estándar y el error estándar al mismo tiempo:

si redirige la salida estándar y el error estándar y luego intenta leer ambos, por ejemplo, usando el siguiente código C #.

[DO#]

string output = p.StandardOutput.ReadToEnd ();

string error = p.StandardError.ReadToEnd ();

p.WaitForExit ();

En este caso, si el proceso secundario escribe cualquier texto en el error estándar, bloqueará el proceso, ya que el proceso principal no puede leer el error estándar hasta que haya terminado de leer el resultado estándar. Sin embargo, el proceso principal no leerá desde la salida estándar hasta que finalice el proceso. Una solución recomendada para esta situación es crear dos subprocesos para que su aplicación pueda leer el resultado de cada flujo en un hilo separado.

http://msdn.microsoft.com/en-us/library/system.diagnostics.processstartinfo.redirectstandardoutput(v=vs.71).aspx

código fluido funcionó en VS2010

 void OnOutputDataReceived(object sender, DataReceivedEventArgs e) { if (String.IsNullOrEmpty(e.Data) == false) { new Thread(() => { this.Dispatcher.Invoke(new Action(() => { // Add you code here })); }).Start(); } } 

Compruebe que la salida que espera no se envía a la salida StandardError en lugar de la salida StandardOutput