ConsoleManager.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. using System;
  2. using System.Diagnostics;
  3. using System.IO;
  4. using System.Runtime.InteropServices;
  5. using System.Security;
  6. namespace GeekDesk.Util
  7. {
  8. [SuppressUnmanagedCodeSecurity]
  9. public static class ConsoleManager
  10. {
  11. private const string Kernel32_DllName = "kernel32.dll";
  12. [DllImport(Kernel32_DllName)]
  13. private static extern bool AllocConsole();
  14. [DllImport(Kernel32_DllName)]
  15. private static extern bool FreeConsole();
  16. [DllImport(Kernel32_DllName)]
  17. private static extern IntPtr GetConsoleWindow();
  18. [DllImport(Kernel32_DllName)]
  19. private static extern int GetConsoleOutputCP();
  20. public static bool HasConsole
  21. {
  22. get { return GetConsoleWindow() != IntPtr.Zero; }
  23. }
  24. /// <summary>
  25. /// Creates a new console instance if the process is not attached to a console already.
  26. /// </summary>
  27. public static void Show()
  28. {
  29. //#if DEBUG
  30. if (!HasConsole)
  31. {
  32. AllocConsole();
  33. InvalidateOutAndError();
  34. }
  35. //#endif
  36. }
  37. /// <summary>
  38. /// 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.
  39. /// </summary>
  40. public static void Hide()
  41. {
  42. //#if DEBUG
  43. if (HasConsole)
  44. {
  45. SetOutAndErrorNull();
  46. FreeConsole();
  47. }
  48. //#endif
  49. }
  50. public static void Toggle()
  51. {
  52. if (HasConsole)
  53. {
  54. Hide();
  55. }
  56. else
  57. {
  58. Show();
  59. }
  60. }
  61. static void InvalidateOutAndError()
  62. {
  63. Type type = typeof(System.Console);
  64. System.Reflection.FieldInfo _out = type.GetField("_out",
  65. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
  66. System.Reflection.FieldInfo _error = type.GetField("_error",
  67. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
  68. System.Reflection.MethodInfo _InitializeStdOutError = type.GetMethod("InitializeStdOutError",
  69. System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
  70. Debug.Assert(_out != null);
  71. Debug.Assert(_error != null);
  72. Debug.Assert(_InitializeStdOutError != null);
  73. _out.SetValue(null, null);
  74. _error.SetValue(null, null);
  75. _InitializeStdOutError.Invoke(null, new object[] { true });
  76. }
  77. static void SetOutAndErrorNull()
  78. {
  79. Console.SetOut(TextWriter.Null);
  80. Console.SetError(TextWriter.Null);
  81. }
  82. }
  83. }