Console redirection of the current process in Mono
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.
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
}
}
}
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.
精彩评论