c# - Redirige la salida de la consola al cuadro de texto en un programa separado
.net winforms (5)
¡Gracias a Marc Maxham por su respuesta que me ahorró tiempo!
Como Jon of All Trades lo notó, UseShellExecute debe establecerse en falso para redirigir las secuencias IO; de lo contrario, la llamada Start () arroja una InvalidOperationException.
Aquí está mi modificación del código donde txtOut es un WPF readonly Textbox
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) ));
}
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.
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 mi aplicación se detenga 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í está el 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);
}
Agregué varios métodos de ayuda a la plataforma O2 (proyecto de código abierto) que le permiten programar fácilmente una interacción con otro proceso a través de la salida y entrada de la consola (consulte http://code.google.com/p/o2platform/source/browse/trunk/O2_Scripts/APIs/Windows/CmdExe/CmdExeAPI.cs )
También es útil para usted la API que permite ver la salida de la consola del proceso actual (en una ventana emergente o de control existente). 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)
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
}
Puedes usar el siguiente código
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();