c# .net redirectstandardoutput startprocessinfo

c# - ProcessInfo y RedirectStandardOutput



.net startprocessinfo (6)

Código de flujo trabajado 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(); } }

Tengo una aplicación que llama a otro proceso en una ventana de comandos y ese proceso tiene estadísticas de actualización que dan salida 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 cambien los resultados dentro de ese proceso o cuando lleguen datos al lector, obtendré eventos.

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


Es interesante que 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, utilice el siguiente código C #.

[DO#]

string output = p.StandardOutput.ReadToEnd ();

error de cadena = p.StandardError.ReadToEnd ();

p.WaitForExit ();

En este caso, si el proceso hijo escribe cualquier texto en un error estándar, bloqueará el proceso, ya que el proceso principal no puede leer el error estándar hasta que haya terminado de leer la salida estándar. Sin embargo, el proceso principal no se leerá desde la salida estándar hasta que el proceso finalice. 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 subproceso separado.

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


He experimentado esto antes A veces, la forma en que el proceso al que llama las salidas a la consola no es compatible con este tipo de redirección de salida. He tenido la suerte en este caso de poder modificar el proceso externo para solucionar esto.

Puede intentar ejecutar su código en otro proceso que salga a la consola y ver si funciona correctamente. Se lee sobre derecho a mí en este momento.

EDITAR:

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

Console.WriteLine(e.Data);

¡Espero que te sirva!

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 de en qué problema se está ejecutando, pero si desea actuar en la salida tan pronto como se genera, intente conectar el evento OutputDataReceived del proceso. Puede especificar controladores para recibir la salida de forma asíncrona 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); }

Consulte el proceso de desactivación de eventos OutputDataReceived para obtener 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<object, DataReceivedEventArgs> 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();


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