views:

167

answers:

2

I am trying to redirect the Console output of a C#/Mono application into a gtk# textview. There are zillions of answers here explaining how to redirect output of a command to whatever output device conceivable. However, I am trying to do the same on the current process. Originally the application was designed as command line, know I want a textview that displays all output. Here is what I have right now:


class Program
{
     Main(string[] args)
     {
           Program prog = new Program();
           Process proc = Process.GetCurrentProcess();
           proc.StartInfo.RedirectStandardOutput =  true;
           proc.StartInfo.RedirectStandardError = true;
           proc.EnableRaisingEvents = true;
           proc.ErrorDataReceived += prog.DataReceived;
           proc.OutputDataReceived += prog.DataReceived;
           proc.BeginErrorReadLine();
           proc.BeginOutputReadLine();
     }
     void DataReceived(object sender, DataReceivedEventArgs e)
     {
           _MainWindow.SendData(e.Data);
     }
}

Is this the right approach? Right now I am receiving the following exception when calling the BeginErrorReadLine() method. The exception is just : Standard Error Can not be redirected. I don't know if the problem is just the Process/Mono thing, or If I am just doing something wrong.

+1  A: 

I believe you can't redirect stdout after the process has started (which is the cases for the current process).

Have a look at the Console.SetOut Method:

Sets the Out property to the specified TextWriter object.

Example:

FileStream fs = new FileStream("Test.txt", FileMode.Create);
StreamWriter sw = new StreamWriter(fs);

Console.SetOut(sw);
Console.WriteLine("Hello World");

This redirects the output of "Hello World" to the text file.

You'd need to implement your own TextWriter that writes all text to the gtk# textview.


Alternatively, since it's your program, you could replace all calls to Console.Write/WriteLine with a custom method that writes the string to the gtk# textview or the console, depending on program argument:

abstract class Stdout
{
    public static readonly Stdout Instance = // ...

    public abstract void WriteLine(string s);

    private class Console : Stdout
    {
        public override void WriteLine(string s)
        {
            Console.WriteLine(s);
        }
    }

    private class Gui : Stdout
    {
        public override void WriteLine(string s)
        {
            // append to gtk# textview
        }
    }
}
dtb
I looked at this before, but I use the writer, then I could only get the Console messages in bulk, right? What I need is that each message is sent independently to the textview.
Freddy
A: 

You may be interested in using Vte. Vte is the terminal emulation widget used by gnome-terminal. It has C# bindings included with gnome-sharp.

You can actually tell it to start a process using one method. Here is the documentation for the Vte.Terminal class. Specifically, look at the ForkCommand() method.

anthony