2009-01-06 13 views
48

Estoy desarrollando una aplicación de Windows Forms que requiere que llame a un programa separado para realizar una tarea. El programa es una aplicación de consola y necesito redireccionar la salida estándar desde la consola a un TextBox en mi programa.Redirige la salida de la consola al cuadro de texto en el programa separado

No tengo problemas para ejecutar el programa desde mi aplicación, pero no sé cómo redirigir la salida a mi aplicación. Necesito capturar la salida mientras el programa se está ejecutando utilizando eventos.

El programa de la consola no debe detenerse hasta que se detenga la aplicación y el texto cambie constantemente a intervalos aleatorios. Lo que intento hacer es simplemente conectar la salida de la consola para activar un controlador de eventos que luego se puede usar para actualizar el TextBox.

Estoy usando C# para codificar el programa y usar el framework .NET para el desarrollo. La aplicación original no es un programa .NET.

EDITAR: Aquí hay un código de ejemplo de lo que intento hacer. En mi aplicación final, reemplazaré Console.WriteLine con código para actualizar el TextBox. Traté de establecer un punto de interrupción en mi controlador de eventos, y ni siquiera se alcanza.

void Method() 
    { 
     var p = new Process(); 
     var path = @"C:\ConsoleApp.exe"; 

     p.StartInfo.FileName = path; 
     p.StartInfo.UseShellExecute = false; 
     p.OutputDataReceived += p_OutputDataReceived; 

     p.Start(); 
    } 

    static void p_OutputDataReceived(object sender, DataReceivedEventArgs e) 
    { 
     Console.WriteLine(">>> {0}", e.Data); 
    } 
+0

¿Dónde está 'InputDataReceived'? –

Respuesta

69

Esto funciona para mí:

void RunWithRedirect(string cmdPath) 
{ 
    var proc = new Process(); 
    proc.StartInfo.FileName = cmdPath; 

    // set up output redirection 
    proc.StartInfo.RedirectStandardOutput = true; 
    proc.StartInfo.RedirectStandardError = true;  
    proc.EnableRaisingEvents = true; 
    proc.StartInfo.CreateNoWindow = true; 
    // see below for output handler 
    proc.ErrorDataReceived += proc_DataReceived; 
    proc.OutputDataReceived += proc_DataReceived; 

    proc.Start(); 

    proc.BeginErrorReadLine(); 
    proc.BeginOutputReadLine(); 

    proc.WaitForExit(); 
} 

void proc_DataReceived(object sender, DataReceivedEventArgs e) 
{ 
    // output will be in string e.Data 
} 
+0

Exactamente lo que quería :) –

+4

Descubrí que a veces (al salir del programa) e.Data es nulo, por lo que debe verificar si e.Data! = Null! – mmmmmmmm

+0

+1 La primera vez que vi algo de este tipo fue en EditPlus. Ahora puedo hacerlo en mis programas .NET. ¡Gracias hombre! –

1
+0

No del todo, necesito capturar texto mientras se está escribiendo en stdout. –

+0

Si sigue el enlace en la publicación, verá el código aquí: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/52e40c0f-66c7-49b1-ba48-457a1ff4a58d/ –

+0

Sí, pero ese código solo se ejecuta una vez. Actualicé mi pregunta para aclarar lo que intento hacer. –

4

Usted puede utilizar el código siguiente

 MemoryStream mem = new MemoryStream(1000); 
     StreamWriter writer = new StreamWriter(mem); 
     Console.SetOut(writer); 

     Assembly assembly = Assembly.LoadFrom(@"C:\ConsoleApp.exe"); 
     assembly.EntryPoint.Invoke(null, null); 
     writer.Close(); 

     string s = Encoding.Default.GetString(mem.ToArray()); 
     mem.Close(); 
+8

Si "C: \ ConsoleApp.exe" no es una aplicación .Net, ¡esto no se ejecutará! – mmmmmmmm

+0

sí, es verdad –

1

He añadido una serie de métodos de ayuda a la (proyecto Open Source) O2 Platform que permiten con facilidad secuencia de comandos de una interacción con otro proceso a través de la entrada y salida de la consola (ver http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs)

También es útil para usted podría ser la API que permite la viewi ng de la salida de la consola del proceso actual (en un control existente o ventana emergente). Vea esta publicación en el blog para más detalles: http://o2platform.wordpress.com/2011/11/26/api_consoleout-cs-inprocess-capture-of-the-console-output/ (este blog también contiene detalles de cómo consumir la salida de la consola de nuevos procesos)

0

¡Gracias a Marc Maxham por su respuesta que me ahorró tiempo!

Como Jon of All Trades lo nota, UseShellExecute debe establecerse en falso para redirigir las secuencias de E/S, de lo contrario, la llamada de Inicio arroja una InvalidOperationException.

Aquí es mi modificación del código donde txtOut es un cuadro de texto de sólo lectura WPF

void RunWithRedirect(string cmdargs) 
    { 
     var proc = new Process() 
     { 
      StartInfo = new ProcessStartInfo("cmd.exe", "/k " + cmdargs) 
      { 
       RedirectStandardOutput = true, 
       RedirectStandardError = true, 
       CreateNoWindow = true 
      }, 
      EnableRaisingEvents = true 
     }; 

     // see below for output handler 
     proc.ErrorDataReceived += proc_DataReceived; 
     proc.OutputDataReceived += proc_DataReceived; 

     proc.Start(); 

     proc.BeginErrorReadLine(); 
     proc.BeginOutputReadLine(); 

     proc.WaitForExit(); 
    } 

    void proc_DataReceived(object sender, DataReceivedEventArgs e) 
    { 
     if (e.Data != null) 
      Dispatcher.BeginInvoke(new Action(() => txtOut.Text += (Environment.NewLine + e.Data))); 
    } 
+0

Modifique la respuesta original en lugar de publicar la suya para que el autor obtenga el crédito (y) –

Cuestiones relacionadas