¿Cómo obtener el resultado de un System.Diagnostics.Process?

Corro ffmpeg así:

System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); p.Start(); p.WaitForExit(); 

… pero el problema es que la consola con ffmpeg aparece y desaparece de inmediato, por lo que no puedo obtener ningún comentario. Ni siquiera sé si el proceso se ejecutó correctamente.

Entonces, ¿cómo puedo yo?

  • Dile a la consola que permanezca abierta

  • Recuperar en C # lo que muestra la consola

Lo que debe hacer es capturar el flujo de salida estándar:

 p.StartInfo.RedirectStandardOutput = true; p.StartInfo.UseShellExecute = false; // instead of p.WaitForExit(), do string q = ""; while ( ! p.HasExited ) { q += p.StandardOutput.ReadToEnd(); } 

Es posible que también deba hacer algo similar con StandardError . A continuación, puede hacer lo que desee con q .

Es un poco quisquilloso, como descubrí en una de mis preguntas

Como ha señalado Jon Skeet, no es inteligente en cuanto al rendimiento usar una concatenación de cadenas como esta; en su lugar, debe usar un StringBuilder :

 p.StartInfo.RedirectStandardOutput = true; p.StartInfo.UseShellExecute = false; // instead of p.WaitForExit(), do StringBuilder q = new StringBuilder(); while ( ! p.HasExited ) { q.Append(p.StandardOutput.ReadToEnd()); } string r = q.ToString(); 

La respuesta de Lucas tiene una condición de carrera: si el proceso finaliza rápidamente, se deja el bucle while (o nunca se ingresa), incluso si queda algo de salida, es posible que se pierda algunos datos. Para evitar eso, se debe realizar otro ReadToEnd después de salir del proceso.

(Tenga en cuenta que en comparación con la versión anterior de mi respuesta, ya no puedo ver la necesidad de WaitForExit una vez que el indicador process.HasExited es verdadero, por lo que esto se reduce a 🙂

 using (var process = Process.Start(startInfo)) { var standardOutput = new StringBuilder(); // read chunk-wise while process is running. while (!process.HasExited) { standardOutput.Append(process.StandardOutput.ReadToEnd()); } // make sure not to miss out on any remaindings. standardOutput.Append(process.StandardOutput.ReadToEnd()); // ... } 

Para una respuesta más específica directamente relacionada con ffmpeg, pasar el comando “-report” a ffmpeg hará que descargue un registro en el directorio actual con lo que se dijo en la pantalla del proceso.

‘-informe’

Vuelque la línea de comando completa y la salida de la consola a un archivo denominado progtwig-AAAAMMDD-HHMMSS.log en el directorio actual. Este archivo puede ser útil para informes de errores. También implica -loglevel verbose.

Nota: establecer la variable de entorno FFREPORT a cualquier valor tiene el mismo efecto.

De la documentación de FFMpeg .

Sé que esta pregunta es antigua, pero la agregaré de todos modos.

Si todo lo que desea hacer es mostrar el resultado de un proceso de línea de comando y está generando el proceso desde una ventana de consola, solo necesita redirigir la entrada estándar (sí, sé que suena mal, pero funciona).

Asi que:

 System.Diagnostics.Process p = new System.Diagnostics.Process(); p.StartInfo = new System.Diagnostics.ProcessStartInfo(ffmpegPath, myParams); p.UseShellExecute = false; p.RedirectStandardInput = true; p.Start(); p.WaitForExit(); 

Haría bien.