2012-05-10 80 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輸出中。 –