private void ColorizeEscapeSequences(TextWriter output, IntPtr hConsole, string message, ushort startingAttribute, ushort defaultAttribute) { lock (this) { int colorStackLength = 0; _colorStack[colorStackLength++] = startingAttribute; ConsoleWin32Api.SetConsoleTextAttribute(hConsole, startingAttribute); int p0 = 0; while (p0 < message.Length) { int p1 = p0; while (p1 < message.Length && message[p1] >= 32) { p1++; } // text if (p1 != p0) { output.Write(message.Substring(p0, p1 - p0)); } if (p1 >= message.Length) { p0 = p1; break; } // control characters char c1 = message[p1]; char c2 = (char)0; if (p1 + 1 < message.Length) { c2 = message[p1 + 1]; } if (c1 == '\a' && c2 == '\a') { output.Write('\a'); p0 = p1 + 2; continue; } if (c1 == '\r' || c1 == '\n') { ConsoleWin32Api.SetConsoleTextAttribute(hConsole, defaultAttribute); output.Write(c1); ConsoleWin32Api.SetConsoleTextAttribute(hConsole, _colorStack[colorStackLength - 1]); p0 = p1 + 1; continue; } if (c1 == '\a') { if (c2 == 'X') { colorStackLength--; ConsoleWin32Api.SetConsoleTextAttribute(hConsole, _colorStack[colorStackLength - 1]); p0 = p1 + 2; continue; } else { ConsoleOutputColor foreground = (ConsoleOutputColor)(int)(c2 - 'A'); ConsoleOutputColor background = (ConsoleOutputColor)(int)(message[p1 + 2] - 'A'); ushort newColor = ColorFromForegroundAndBackground( _colorStack[colorStackLength - 1], foreground, background); _colorStack[colorStackLength++] = newColor; ConsoleWin32Api.SetConsoleTextAttribute(hConsole, newColor); p0 = p1 + 3; continue; } } output.Write(c1); p0 = p1 + 1; } if (p0 < message.Length) { output.Write(message.Substring(p0)); } } }
private void Output(LogEventInfo logEvent, string message) { IntPtr hConsole = ConsoleWin32Api.GetStdHandle(ErrorStream ? ConsoleWin32Api.STD_ERROR_HANDLE : ConsoleWin32Api.STD_OUTPUT_HANDLE); ConsoleWin32Api.CONSOLE_SCREEN_BUFFER_INFO csbi; ConsoleWin32Api.GetConsoleScreenBufferInfo(hConsole, out csbi); ConsoleRowHighlightingRule matchingRule = null; foreach (ConsoleRowHighlightingRule cr in RowHighlightingRules) { if (cr.CheckCondition(logEvent)) { matchingRule = cr; break; } } if (UseDefaultRowHighlightingRules && matchingRule == null) { foreach (ConsoleRowHighlightingRule cr in _defaultConsoleRowHighlightingRules) { if (cr.CheckCondition(logEvent)) { matchingRule = cr; break; } } } if (matchingRule == null) { matchingRule = ConsoleRowHighlightingRule.Default; } ushort newColor = ColorFromForegroundAndBackground(csbi.wAttributes, matchingRule.ForegroundColor, matchingRule.BackgroundColor); message = message.Replace("\a", "\a\a"); foreach (ConsoleWordHighlightingRule hl in WordHighlightingRules) { message = hl.ReplaceWithEscapeSequences(message); } if (ErrorStream) { ColorizeEscapeSequences(Console.Error, hConsole, message, newColor, csbi.wAttributes); } else { ColorizeEscapeSequences(Console.Out, hConsole, message, newColor, csbi.wAttributes); } ConsoleWin32Api.CONSOLE_SCREEN_BUFFER_INFO csbi2; ConsoleWin32Api.GetConsoleScreenBufferInfo(hConsole, out csbi2); ConsoleWin32Api.SetConsoleTextAttribute(hConsole, csbi.wAttributes); int xsize = csbi2.dwSize.x; int xpos = csbi2.dwCursorPosition.x; uint written = 0; ConsoleWin32Api.FillConsoleOutputAttribute(hConsole, newColor, xsize - xpos, csbi2.dwCursorPosition, out written); ConsoleWin32Api.SetConsoleTextAttribute(hConsole, csbi.wAttributes); if (ErrorStream) { Console.Error.WriteLine(); } else { Console.WriteLine(); } }