Wednesday, May 04, 2005

Console window for a Windows application (.NET C#)

Here is all the code you will need to start up a console window for your windows application. I found the console window extremely useful in logging of error messages as well as tracing program execution. When you call the CreateConsole method, it checks a registry key to see if it should create a console window. (in this code, this is done by the line string showConsole = FileSystem.QueryRegistryValue("DebugConsole"); Where QueryRegistryValue is a method we implemented). The reason I did this, is that we could then ask the end user to add that key to his registry and he would be able to see the trace console window, which could then be used to diagnose problems. When a console is created this code will disable the close button. (I found that if you tried closing the console, it would crash the application.) To close the console, call the method DestoryConsole. You can change the color of the output text using some form of the methods "SetForeGroundColour". ---------------------------------------- public class SystemUtilities { private static bool _bShowConsole = false; // constants for console streams const int STD_INPUT_HANDLE = -10; const int STD_OUTPUT_HANDLE = -11; const int STD_ERROR_HANDLE = -12; [Flags] public enum ForeGroundColour { Black = 0x0000, Blue = 0x0001, Green = 0x0002, Cyan = 0x0003, Red = 0x0004, Magenta = 0x0005, Yellow = 0x0006, Grey = 0x0007, White = 0x0008 } private class Win32 { // colours that can be set [DllImport("kernel32.dll")] public static extern Boolean AllocConsole(); [DllImport("kernel32.dll")] public static extern Boolean FreeConsole(); [DllImportAttribute("Kernel32.dll")] public static extern IntPtr GetStdHandle (int nStdHandle); // input, output, or error device [DllImportAttribute("Kernel32.dll")] public static extern Boolean SetConsoleTextAttribute ( IntPtr hConsoleOutput, int wAttributes); [DllImport("Kernel32.Dll")] public static extern Boolean SetConsoleTitle ( string lpConsoleTitle ); [DllImport("Kernel32.Dll")] public static extern int GetConsoleTitle ( StringBuilder lpConsoleTitle, int titleSize); [DllImport("User32.Dll")] public static extern IntPtr FindWindow( string lpClassName, string lpWindowName); [DllImport("User32.Dll")] public static extern IntPtr GetSystemMenu( IntPtr hWnd, bool bRevert); [DllImport("User32.Dll")] public static extern Boolean DeleteMenu( IntPtr hMenu, int uPosition, int uFlags ); [DllImport("User32.Dll")] public static extern Boolean DrawMenuBar( IntPtr hWnd ); } public static bool DebugConsoleVisible { get { return _bShowConsole; } } //displays the console only if the registry has the key DebugConsole set to "show" public static bool CreateConsole() { string showConsole = FileSystem.QueryRegistryValue("DebugConsole"); if (showConsole != null && showConsole == "show") { _bShowConsole = Win32.AllocConsole(); //retrieve the window title of the console window StringBuilder consoleTitle = new StringBuilder(256); Win32.GetConsoleTitle(consoleTitle,256); string newConsoleTitle = "MyTraceWindow for " + consoleTitle.ToString(); //reset the window title Win32.SetConsoleTitle(newConsoleTitle); //search for the handle using window's name IntPtr hWnd = IntPtr.Zero; while (hWnd == IntPtr.Zero) { hWnd = Win32.FindWindow(null, newConsoleTitle); } //disable the windows close button IntPtr hMenu = Win32.GetSystemMenu( hWnd, false ); if ( hMenu != IntPtr.Zero ) { Win32.DeleteMenu(hMenu, 61536 , 0); Win32.DrawMenuBar(hWnd); } // if ( hMenu != NULL ) } return _bShowConsole; } public static bool DestroyConsole() { if (_bShowConsole == true) _bShowConsole = Win32.FreeConsole(); return _bShowConsole; } public static bool SetForeGroundColour() { // default to a white-grey return SetForeGroundColour(ForeGroundColour.Grey); } public static bool SetForeGroundColour(ForeGroundColour foreGroundColour) { // default to a bright white-grey return SetForeGroundColour(foreGroundColour, true); } public static bool SetForeGroundColour(ForeGroundColour foreGroundColour, bool brightColours) { if (_bShowConsole == true) { // get the current console handle IntPtr nConsole = Win32.GetStdHandle(STD_OUTPUT_HANDLE); int colourMap; // if we want bright colours OR it with white if (brightColours) colourMap = (int) foreGroundColour | (int) ForeGroundColour.White; else colourMap = (int) foreGroundColour; // call the api and return the result return Win32.SetConsoleTextAttribute(nConsole, colourMap); } // if (_bShowConsole == true) else { return false; } } private SystemUtilities() { // // TODO: Add constructor logic here // } }

1 comment:

Raj Rao said...

The code can now be found at: