2012-05-10 84 views
4

我正在编写一个控制台应用程序,其中有一个自定义记录器。记录器需要以红色将所有发送到Console.Error的颜色着色。我现在有第三方引用,也写入Console.Out和Console.Error,所以我必须以一种方式来解决这个问题,因为我没有他们的源代码。我已经安装了我的记录器,以便通过调用Console.SetOut & Console.SetError方法来写入控制台的任何代码将使用我的记录器的TextWriter。它的有点工作,但我猜是有某种同步问题?在我的ErrorWriter类中,你可以看到我正在设置控制台的前景色,然后调用base.Write(),但结果不符合预期。来自控制台的文本应该是灰色的,会出现红色,中间会突然变成灰色。在相同的字符位置,它一直从红色变回灰色,但我假设base.Write()实际上不会立即吐出到控制台;有某种滞后时间/缓冲区。我试过调用base.Flush(),但是这使得来自Console.Out的所有文本更加糟糕。我该如何解决这个问题?设置Console.Error的颜色写入

public class Logger 
{ 
    private static TextWriter _out; 
    private static ErrorWriter _error; 

    public Logger() 
    { 
     Initiliaze(); 
    } 

    public static TextWriter Out 
    { 
     get 
     { 
      return _out; 
     } 
    } 

    public static TextWriter Error 
    { 
     get 
     { 
      return _error; 
     } 
    } 

    private static void Initiliaze() 
    { 
     if (_out == null) 
      _out = new StreamWriter(Console.OpenStandardOutput()); 
     if (_error == null) 
      _error = new ErrorWriter(Console.OpenStandardError()); 

     Console.SetOut(Out); 
     Console.SetOut(Error); 
    } 
} 

public class ErrorWriter : StreamWriter 
{ 
    // constructors omitted to save space 

    public override void Write(string value) 
    { 
      Console.ForegroundColor = ConsoleColor.Red; 
      base.Write(value); 
      //base.Flush(); 
      Console.ResetColor(); 
    } 

    public override Encoding Encoding 
    { 
     get { return Encoding.Default; } 
    } 
} 
+0

请参阅:http://stackoverflow.com/questions/1522936/how-do-i-lock-the-console-across-threads-in- c-net –

+1

这实际上不起作用。 .ForegroundColor只能修改stdout而不修改stderr。如果重定向stdout,则颜色变化不会出现在stderr输出 –

回答

1

原来是一个愚蠢的复制/粘贴错误!我有两个对Console.SetOut()的调用。现在它的工作后,改变第二个Console.SetError()

2

可以装饰的方法,为了做到这一点:

public class ConsoleErrorWriterDecorator : TextWriter 
{ 
    private TextWriter m_OriginalConsoleStream; 

    public ConsoleErrorWriterDecorator(TextWriter consoleTextWriter) 
    { 
     m_OriginalConsoleStream = consoleTextWriter; 
    } 

    public override void WriteLine(string value) 
    { 
     ConsoleColor originalColor = Console.ForegroundColor; 
     Console.ForegroundColor = ConsoleColor.Red; 

     m_OriginalConsoleStream.WriteLine(value); 

     Console.ForegroundColor = originalColor; 
    } 

    public override Encoding Encoding 
    { 
     get { return Encoding.Default; } 
    } 

    public static void SetToConsole() 
    { 
     Console.SetError(new ConsoleErrorWriterDecorator(Console.Error)); 
    } 
} 

不要忘了运行 “ConsoleErrorWriterDecorator.SetToConsole();”在你开始写控制台之前

+0

这实际上不起作用。 .ForegroundColor只能修改stdout而不修改stderr。如果重定向stdout,则颜色更改不会出现在stderr输出中。 –