Kon.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Security.Permissions;
  4. namespace BepInEx.ConsoleUtil
  5. {
  6. internal class Kon
  7. {
  8. #region pinvoke
  9. [DllImport("kernel32.dll", SetLastError = true)]
  10. private static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
  11. [DllImport("kernel32.dll", SetLastError = true)]
  12. private static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, short attributes);
  13. [DllImport("kernel32.dll", SetLastError = true)]
  14. private static extern IntPtr GetStdHandle(int nStdHandle);
  15. #endregion
  16. #region Types
  17. private struct CONSOLE_SCREEN_BUFFER_INFO
  18. {
  19. internal COORD dwSize;
  20. internal COORD dwCursorPosition;
  21. internal short wAttributes;
  22. internal SMALL_RECT srWindow;
  23. internal COORD dwMaximumWindowSize;
  24. }
  25. private struct COORD
  26. {
  27. internal short X;
  28. internal short Y;
  29. }
  30. private struct SMALL_RECT
  31. {
  32. internal short Left;
  33. internal short Top;
  34. internal short Right;
  35. internal short Bottom;
  36. }
  37. private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
  38. #endregion
  39. #region Private
  40. private static short ConsoleColorToColorAttribute(short color, bool isBackground)
  41. {
  42. if ((color & -16) != 0)
  43. throw new ArgumentException("Arg_InvalidConsoleColor");
  44. if (isBackground)
  45. color <<= 4;
  46. return color;
  47. }
  48. private static CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded)
  49. {
  50. succeeded = false;
  51. if (!(conOut == INVALID_HANDLE_VALUE))
  52. {
  53. CONSOLE_SCREEN_BUFFER_INFO console_SCREEN_BUFFER_INFO;
  54. if (!GetConsoleScreenBufferInfo(conOut, out console_SCREEN_BUFFER_INFO))
  55. {
  56. bool consoleScreenBufferInfo = GetConsoleScreenBufferInfo(GetStdHandle(-12), out console_SCREEN_BUFFER_INFO);
  57. if (!consoleScreenBufferInfo)
  58. consoleScreenBufferInfo = GetConsoleScreenBufferInfo(GetStdHandle(-10), out console_SCREEN_BUFFER_INFO);
  59. if (!consoleScreenBufferInfo)
  60. if (Marshal.GetLastWin32Error() == 6 && !throwOnNoConsole)
  61. return default(CONSOLE_SCREEN_BUFFER_INFO);
  62. }
  63. succeeded = true;
  64. return console_SCREEN_BUFFER_INFO;
  65. }
  66. if (!throwOnNoConsole)
  67. return default(CONSOLE_SCREEN_BUFFER_INFO);
  68. throw new Exception("IO.IO_NoConsole");
  69. }
  70. private static void SetConsoleColor(bool isBackground, ConsoleColor c)
  71. {
  72. new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
  73. var color = ConsoleColorToColorAttribute((short)c, isBackground);
  74. bool flag;
  75. var bufferInfo = GetBufferInfo(false, out flag);
  76. if (!flag)
  77. return;
  78. var num = bufferInfo.wAttributes;
  79. num &= (short)(isBackground ? -241 : -16);
  80. num = (short)((ushort)num | (ushort)color);
  81. SetConsoleTextAttribute(conOut, num);
  82. }
  83. private static ConsoleColor GetConsoleColor(bool isBackground)
  84. {
  85. bool flag;
  86. var bufferInfo = GetBufferInfo(false, out flag);
  87. if (!flag)
  88. return isBackground ? ConsoleColor.Black : ConsoleColor.Gray;
  89. return ColorAttributeToConsoleColor((short)(bufferInfo.wAttributes & 240));
  90. }
  91. private static ConsoleColor ColorAttributeToConsoleColor(short c)
  92. {
  93. if ((short)(c & 255) != 0)
  94. c >>= 4;
  95. return (ConsoleColor)c;
  96. }
  97. internal static IntPtr conOut = IntPtr.Zero;
  98. #endregion
  99. #region Public
  100. public static void ResetConsoleColor()
  101. {
  102. SetConsoleColor(true, ConsoleColor.Black);
  103. SetConsoleColor(false, ConsoleColor.Gray);
  104. }
  105. public static ConsoleColor ForegroundColor
  106. {
  107. get { return GetConsoleColor(false); }
  108. set { SetConsoleColor(false, value); }
  109. }
  110. public static ConsoleColor BackgroundColor
  111. {
  112. get { return GetConsoleColor(true); }
  113. set { SetConsoleColor(true, value); }
  114. }
  115. #endregion
  116. }
  117. }