2010-09-04 17 views
11

Por el momento estoy empezando un archivo por lotes de mi programa en C# con:Redirigir la salida (stdout, stderr) de un proceso hijo a la ventana Resultados de Visual Studio

System.Diagnostics.Process.Start(@"DoSomeStuff.bat"); 

Lo que me gustaría ser capaz de hacer es redirigir la salida (stdout y stderr) de ese proceso secundario a la ventana de Salida en Visual Studio (específicamente Visual C# Express 2008).

¿Hay alguna manera de hacerlo?

(Además:. Tal que no todo está tamponado y luego escupió a la ventana de resultados cuando el proceso hijo termina)


(Por cierto: En el momento en que puedo conseguir la salida estándar (pero no stderr) de la padres proceso que aparezca en la ventana de salida, haciendo mi programa de una "aplicación para Windows" en lugar de una "Aplicación de consola". esto rompe si el programa se ejecuta fuera de Visual Studio, pero esto está bien en mi caso particular .)

+0

Todas las piezas están aquí. Redirija la salida para el proceso, use Trace para obtenerlo en la ventana de Salida. –

+0

¿Has descubierto cómo redirigir el resultado de un proceso secundario? Las respuestas dadas a continuación podrían redirigir el resultado de un proceso principal pero no uno secundario. – Fiona

Respuesta

20
process.StartInfo.CreateNoWindow = true; 
process.StartInfo.UseShellExecute = false; 
process.StartInfo.RedirectStandardOutput = true; 
process.OutputDataReceived += (sender, args) => Console.WriteLine(args.Data); 
process.Start(); 
process.BeginOutputReadLine(); 

process.WaitForExit(); 

La misma idea de Error, basta con sustituir Output en esos nombres método/propiedad.

+6

Esta respuesta es en su mayoría correcta. Le faltan algunas cosas. En particular: 'Comience' antes de' Begin ... ReadLine' y 'WaitForExit' después. Al establecer 'RedirectStandardInput' en true, se corrigió un problema causado por uno de los programas (específicamente plink) en el archivo de proceso por lotes que deseaba un stdin válido, aunque no lo usara. –

+0

'WaitForExit()' puede causar una espera infinita. Siempre llame al método con un tiempo de espera: 'process.WaitForExit (10000)' => espera 10 segundos. –

-3

¿Ha considerado usar un DefaultTraceListener?

//Create and add a new default trace listener. 
    DefaultTraceListener defaultListener; 
    defaultListener = new DefaultTraceListener(); 
    Trace.Listeners.Add(defaultListener); 
+2

Esto ni siquiera * remotamente * responde mi pregunta. Y desde la página de MSDN vinculado: "Una instancia de esta clase se añade automáticamente a los Debug.Listeners y Trace.Listeners colecciones de añadir explícitamente una segunda DefaultTraceListener hace que los mensajes duplicados en la ventana de salida de un depurador y duplicar cuadros de mensaje para asevera.", Haciendo tu respuesta es peor que totalmente inútil. –

+4

Voto venganza, ¿eh? Mantente con clase, GenEric35. –

+0

+1 para la explicación de la página MSDN de Anderw – prabhakaran

2

Lo que sucede aquí es que Visual Studio muestra la salida de depuración del programa en la ventana de resultados. Es decir: si usa Trace.WriteLine, aparecerá en la Ventana de salida, debido al oyente de seguimiento predeterminado.

De alguna manera, su aplicación de Windows Form (cuando usa Console.WriteLine; supongo que está utilizando Console.WriteLine) también está escribiendo resultados de depuración, y Visual Studio está recogiendo esto.

No hará lo mismo para procesos secundarios, a menos que capture explícitamente la salida y lo redirija junto con su resultado.

+0

Eso es básicamente lo que intento preguntar: ¿cómo se hace la última parte? (Y, me di cuenta de que me estaba perdiendo esto de mi pregunta: ¿cómo hacerlo "tal como sucede"?) –

8

Una variación de esto funciona para mí, publicar esto ahora porque me gustaría haberlo encontrado antes. Tenga en cuenta que esto es solo un fragmento extraído del código real, por lo que puede haber errores triviales.

La técnica se basa en un código de MSDN. Lo que no he podido averiguar es cómo hacer que la ventana de salida se actualice "sobre la marcha". No se actualiza hasta después de que esta tarea regrese.

// Set this to your output window Pane 
private EnvDTE.OutputWindowPane _OutputPane = null; 

// Methods to receive standard output and standard error 

private static void StandardOutputReceiver(object sendingProcess, DataReceivedEventArgs outLine) 
{ 
    // Receives the child process' standard output 
    if (! string.IsNullOrEmpty(outLine.Data)) { 
     if (_OutputPane != null) 
      _OutputPane.Write(outLine.Data + Environment.NewLine); 
    } 
} 

private static void StandardErrorReceiver(object sendingProcess, DataReceivedEventArgs errLine) 
{ 
    // Receives the child process' standard error 
    if (! string.IsNullOrEmpty(errLine.Data)) { 
     if (_OutputPane != null) 
      _OutputPane.Write("Error> " + errLine.Data + Environment.NewLine); 
    } 
} 

// main code fragment 
{ 
    // Start the new process 
    ProcessStartInfo startInfo = new ProcessStartInfo(PROGRAM.EXE); 
    startInfo.Arguments = COMMANDLINE; 
    startInfo.WorkingDirectory = srcDir; 
    startInfo.UseShellExecute = false; 
    startInfo.RedirectStandardOutput = true; 
    startInfo.RedirectStandardError = true; 
    startInfo.CreateNoWindow = true; 
    Process p = Process.Start(startInfo); 
    p.OutputDataReceived += new DataReceivedEventHandler(StandardOutputReceiver); 
    p.BeginOutputReadLine(); 
    p.ErrorDataReceived += new DataReceivedEventHandler(StandardErrorReceiver); 
    p.BeginErrorReadLine(); 
    bool completed = p.WaitForExit(20000); 
    if (!completed) 
    { 
     // do something here if it didn't finish in 20 seconds 
    } 
    p.Close(); 
} 
+0

Esto no obtendrá stdout y stderror en el orden correcto .. – paulm

+0

@paulm ¿a qué te refieres con que no obtendrá el orden correcto? Este código no funciona para mí al redireccionar el stderr (stdout está funcionando). ¿Alguna idea de por qué? – rboy

+0

Use la respuesta de mi pregunta: esto no será stderr y stdout en el orden correcto, es decir, si la aplicación no funciona, se equivoca, se extravía, puede salir, errar, errar, etc. – paulm

Cuestiones relacionadas