hash_bucket()

Creating Consoles…

Posted on: August 15, 2006

While the standard debug console in Visual Studio is a nice bucket to throw your debug stuff into, sometimes I find the company of a good old console next to my app a lot more easy to keep track of. However, in order to get a console up and running when executing managed code you have to perform some p/Invoke magic that goes something like this:

using System.Runtime.InteropServices;

[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();

Add(import) these static classes to some class of yours and then call them whenever you need to open or close a console window. Basically, once you’ve allocated a Console, anything sent to Cosnole.Write() or Console.WriteLine() will be printed to your new Console window:

Foo.AllocConsole();
Console.SetWindowSize(80, 20);
Console.SetBufferSize(80, 40);
Console.WriteLine(“Hello Console”);
Foo.FreeConsole();

Be aware though that if you do not create this console on its own thread, the next time you call AllocConsole() it will be silently ignored and the output to your *new* console will be swallowed by the previously created one. Also if you close the new console window it will drag your main application with it in the fall…

Update:

If you also add this:

[DllImport(“kernel32.dll”)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);

little function and create a delegate:

delegate bool ConsoleControlDelegate(CtrlMsgTypes msg);

then add an Enum (all in good faith of interop):

enum CtrlMsgTypes : uint
{
_C_EVENT = 0,
_BREAK_EVENT,
_CLOSE_EVENT,
_LOGOFF_EVENT = 5,
_SHUTDOWN_EVENT
}

and a function:

private bool ctrlHandler(CtrlMsgTypes msg)
{
switch (msg)
{
case CtrlMsgTypes._C_EVENT:
FreeConsole();
return true;
case CtrlMsgTypes._BREAK_EVENT:
FreeConsole();
return true;
case CtrlMsgTypes._CLOSE_EVENT:
return true;
case CtrlMsgTypes._LOGOFF_EVENT:
return false;
case CtrlMsgTypes._SHUTDOWN_EVENT:
return false;
default:
return false;
}
return false;
}

then call the new function after Alloc()ating the new console:

where this.consoleDelegate is a instance created somewhere else (remember that if you do not keep a reference to the delegate alive for the time is might be called by the console, the GC might collect it and then the console will have no delegate to call anymore (thus resulting in a CallBackOnCollectedDelegate…)):

SetConsoleCtrlHandler(this.consoleDelegate, true);

This at least lets the user press Ctrl+c to log out from the created console without closing the whole application, though the Close button still causes the same behaviour…

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

.

This blog has no clear focus. It has a focus though, it's just not very clear at the moment...

Dev Env.

Visual Studio 2008 Prof / NUnit / Gallio / csUnit / STools (ExactMagic) / doxygen / dxCore / TypeMock / TestDriven.net / SequenceViz / CLRProfiler / Snoop / Reflector / Mole / FxCop / Subversion / TortoiseSVN / SlikSVN / CruiseControl.net / msbuild / nant

Blog Stats

  • 81,524 hits