Kon.cs 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  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) return;
  77. var num = bufferInfo.wAttributes;
  78. num &= (short)(isBackground ? -241 : -16);
  79. num = (short)((ushort)num | (ushort)color);
  80. SetConsoleTextAttribute(conOut, num);
  81. }
  82. private static ConsoleColor GetConsoleColor(bool isBackground)
  83. {
  84. bool flag;
  85. var bufferInfo = GetBufferInfo(false, out flag);
  86. if (!flag) return isBackground ? ConsoleColor.Black : ConsoleColor.Gray;
  87. return ColorAttributeToConsoleColor((short)(bufferInfo.wAttributes & 240));
  88. }
  89. private static ConsoleColor ColorAttributeToConsoleColor(short c)
  90. {
  91. if ((short)(c & 255) != 0)
  92. c >>= 4;
  93. return (ConsoleColor)c;
  94. }
  95. internal static IntPtr conOut = IntPtr.Zero;
  96. #endregion
  97. #region Public
  98. public static void ResetConsoleColor()
  99. {
  100. SetConsoleColor(true, ConsoleColor.Black);
  101. SetConsoleColor(false, ConsoleColor.Gray);
  102. }
  103. public static ConsoleColor ForegroundColor
  104. {
  105. get
  106. {
  107. return GetConsoleColor(false);
  108. }
  109. set
  110. {
  111. SetConsoleColor(false, value);
  112. }
  113. }
  114. public static ConsoleColor BackgroundColor
  115. {
  116. get
  117. {
  118. return GetConsoleColor(true);
  119. }
  120. set
  121. {
  122. SetConsoleColor(true, value);
  123. }
  124. }
  125. #endregion
  126. }
  127. }