ColoredConsoleAppender calls Console.OpenStandardOutput() in ActivateOptions to store a Stream that represents the console. When you create a console in a WinForm app you need to call ActivateOptions again so the internal Stream can be re-initialized:
public partial class Form1 : Form { [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AttachConsole(int dwProcessId); public Form1() { InitializeComponent(); var appender = new ColoredConsoleAppender(); var mapping = new ColoredConsoleAppender.LevelColors { Level = Level.Debug, ForeColor = ColoredConsoleAppender.Colors.Red, BackColor = ColoredConsoleAppender.Colors.Blue }; appender.AddMapping(mapping); appender.ActivateOptions(); appender.Layout = new SimpleLayout(); BasicConfigurator.Configure(appender); SetConsole(); ILog log = LogManager.GetLogger(typeof(Form1)); log.Debug("Hello World"); } public static void SetConsole() { foreach (IAppender appender in LogManager.GetRepository().GetAppenders()) { var coloredConsole = appender as ColoredConsoleAppender; if (coloredConsole != null) { if (AllocConsole()) { AttachConsole(-1); coloredConsole.ActivateOptions(); } return; } } } } ________________________________ From: Michael SALOMON <michaelsalomo...@gmail.com> To: log4net-user@logging.apache.org Sent: Friday, June 26, 2009 9:21:31 AM Subject: Problem using a ConsoleAppender in a Windows Form application Hi ! I'm using log4net 1.2.10.0 and .NET 2.0 I wrote a Windows Form application and I want to be able to log debug messages in a ColoredConsoleAppender (or whatever type of Console appender). If I compile my application as a Console Application, this works fine... If I compile it as a Windows Forms application, then I understand that no console is attached to my application, fair enough.. In this case I programmaticaly attach a brand new console by using this piece of code : [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool AllocConsole(); [DllImport("kernel32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] static extern bool FreeConsole(); [DllImport("kernel32.dll", SetLastError = true)] private static extern bool AttachConsole(int dwProcessId); public static void SetConsole() { foreach (log4net.Appender.IAppender appender in log4net.LogManager.GetRepository().GetAppenders()) { System.Type type = appender.GetType(); if ((type == typeof(log4net.Appender.ColoredConsoleAppender)) || (type == typeof(log4net.Appender.ConsoleAppender))) { if (AllocConsole()) AttachConsole(-1); return; } } So at startup, if any console appender is found, I attach a console... At this stage, I can do things like : Console.WriteLine() , and it works very fine, I can see the messages in my new console... But for some reason, the Console Appenders do not forward their messages to this console... Do I miss something or do something wrong ? I tried to create a custom appender that inherits ConsoleAppender and do something like: protected override void Append (LoggingEvent loggingEvent) { Console.WriteLine (RenderLoggingEvent(loggingEvent); } This works fine with my attached console, but I loose all the nice colored features... And fact is I do want them :) Thanks a lot for your help Michael