views:

7359

answers:

3

I'm developing an Windows Forms application that requires me to call a separate program to perform a task. The program is a console application and I need to redirect standard output from the console to a TextBox in my program.

I have no problem executing the program from my application, but I don't know how to redirect the output to my application. I need to capture output while the program is running using events.

The console program isn't meant to stop running until my application stops and the text changes constantly at random intervals. What I'm attempting to do is simply hook output from the console to trigger an event handler which can then be used to update the TextBox.

I am using C# to code the program and using the .NET framework for development. The original application is not a .NET program.

EDIT: Here's example code of what I'm trying to do. In my final app, I'll replace Console.WriteLine with code to update the TextBox. I tried to set a breakpoint in my event handler, and it isn't even reached.

    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);
    }
+1  A: 

See http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/72cf626c-92c1-4988-b559-39b91a173181/.

Ben Alpert
Not quite, I need to capture text as it is being written to stdout.
If you follow the link in the post, you'll see code for that here: http://social.msdn.microsoft.com/forums/en-US/csharpgeneral/thread/52e40c0f-66c7-49b1-ba48-457a1ff4a58d/
Brian Rasmussen
Yes, but that code only runs once. I updated my question to clarify what I'm attempting to do.
+11  A: 

This works for me:

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
}
Mark Maxham
Exactly what I wanted :)
I discovered that sometimes (on program exit) e.Data is null, so you have to check if e.Data != null!
rstevens
+1 First time I saw something of this sort was in EditPlus. Now I can do it in my .NET programs. Thanks man!
Alex Essilfie
+1  A: 

You can use the following code

        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();
Ahmed Said
If "C:\ConsoleApp.exe" is not a .Net application this would not run!
rstevens
yes that is true
Ahmed Said