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 <[email protected]>
To: [email protected]
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