publicstaticclassConsoleManager{privateconst string Kernel32_DllName ="kernel32.dll";[DllImport(Kernel32_DllName)]privatestatic extern bool AllocConsole();[DllImport(Kernel32_DllName)]privatestatic extern bool FreeConsole();[DllImport(Kernel32_DllName)]privatestatic extern IntPtr GetConsoleWindow();[DllImport(Kernel32_DllName)]privatestatic extern int GetConsoleOutputCP();publicstatic bool HasConsole
{get{returnGetConsoleWindow()!= IntPtr.Zero;}}/// Creates a new console instance if the process is not attached to a console already. publicstaticvoidShow(){
#ifDEBUGif(!HasConsole){AllocConsole();InvalidateOutAndError();}
#endif
}/// If the process has a console attached to it, it will be detached and no longer visible. Writing to the System.Console is still possible, but no output will be shown. publicstaticvoidHide(){
#ifDEBUGif(HasConsole){SetOutAndErrorNull();FreeConsole();}
#endif
}publicstaticvoidToggle(){if(HasConsole){Hide();}else{Show();}}staticvoidInvalidateOutAndError(){
Type type =typeof(System.Console);
System.Reflection.FieldInfo _out = type.GetField("_out",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
System.Reflection.FieldInfo _error = type.GetField("_error",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod("InitializeStdOutError",
System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
Debug.Assert(_out !=null);
Debug.Assert(_error !=null);
Debug.Assert(_InitializeStdOutError !=null);
_out.SetValue(null,null);
_error.SetValue(null,null);
_InitializeStdOutError.Invoke(null,newobject[]{true});}staticvoidSetOutAndErrorNull(){
Console.SetOut(TextWriter.Null);
Console.SetError(TextWriter.Null);}}