Bladeren bron

ConsoleColor support

exdownloader 6 jaren geleden
bovenliggende
commit
7b48707ba3
3 gewijzigde bestanden met toevoegingen van 164 en 4 verwijderingen
  1. 1 0
      BepInEx/BepInEx.csproj
  2. 11 4
      BepInEx/ConsoleUtil/ConsoleWindow.cs
  3. 152 0
      BepInEx/ConsoleUtil/Kon.cs

+ 1 - 0
BepInEx/BepInEx.csproj

@@ -58,6 +58,7 @@
     <Compile Include="ConsoleUtil\ConsoleMirror.cs" />
     <Compile Include="ConsoleUtil\ConsoleWindow.cs" />
     <Compile Include="ConsoleUtil\Extensions.cs" />
+    <Compile Include="ConsoleUtil\Kon.cs" />
     <Compile Include="ConsoleUtil\SafeConsole.cs" />
     <Compile Include="Chainloader.cs" />
     <Compile Include="BaseUnityPlugin.cs" />

+ 11 - 4
BepInEx/ConsoleUtil/ConsoleWindow.cs

@@ -26,13 +26,17 @@ namespace UnityInjector.ConsoleUtil
             // Store Current Window
             IntPtr currWnd = GetForegroundWindow();
 
-            if (!AllocConsole())
-                throw new Exception("AllocConsole() failed");
+            //Check for existing console before allocating
+            if (GetConsoleWindow() == IntPtr.Zero)
+                if (!AllocConsole())
+                    throw new Exception("AllocConsole() failed");
 
             // Restore Foreground
             SetForegroundWindow(currWnd);
 
-            _cOut = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
+            _cOut = CreateFile("CONOUT$", 0x80000000 | 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
+            BepInEx.ConsoleUtil.Kon.conOut = _cOut;
+
             if (!SetStdHandle(-11, _cOut))
                 throw new Exception("SetStdHandle() failed");
             Init();
@@ -65,13 +69,16 @@ namespace UnityInjector.ConsoleUtil
         [DllImport("kernel32.dll", SetLastError = true)]
         private static extern bool AllocConsole();
 
+        [DllImport("kernel32.dll")]
+        private static extern IntPtr GetConsoleWindow();
+
         [DllImport("kernel32.dll", ExactSpelling = true, SetLastError = true)]
         private static extern bool CloseHandle(IntPtr handle);
 
         [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
         private static extern IntPtr CreateFile(
             string fileName,
-            int desiredAccess,
+            uint desiredAccess,
             int shareMode,
             IntPtr securityAttributes,
             int creationDisposition,

+ 152 - 0
BepInEx/ConsoleUtil/Kon.cs

@@ -0,0 +1,152 @@
+using System;
+using System.Runtime.InteropServices;
+using System.Security.Permissions;
+
+namespace BepInEx.ConsoleUtil
+{
+    internal class Kon
+    {
+        #region pinvoke
+
+        [DllImport("kernel32.dll", SetLastError = true)]
+        private static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
+
+        [DllImport("kernel32.dll", SetLastError = true)]
+        private static extern bool SetConsoleTextAttribute(IntPtr hConsoleOutput, short attributes);
+
+        [DllImport("kernel32.dll", SetLastError = true)]
+        private static extern IntPtr GetStdHandle(int nStdHandle);
+
+        #endregion
+
+        #region Types
+
+        private struct CONSOLE_SCREEN_BUFFER_INFO
+        {
+            internal COORD dwSize;
+            internal COORD dwCursorPosition;
+            internal short wAttributes;
+            internal SMALL_RECT srWindow;
+            internal COORD dwMaximumWindowSize;
+        }
+
+        private struct COORD
+        {
+            internal short X;
+            internal short Y;
+        }
+
+        private struct SMALL_RECT
+        {
+            internal short Left;
+            internal short Top;
+            internal short Right;
+            internal short Bottom;
+        }
+
+        private static readonly IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
+
+        #endregion
+
+        #region Private
+
+        private static short ConsoleColorToColorAttribute(short color, bool isBackground)
+        {
+            if ((color & -16) != 0)
+                throw new ArgumentException("Arg_InvalidConsoleColor");
+            if (isBackground)
+                color <<= 4;
+            return color;
+        }
+
+        private static CONSOLE_SCREEN_BUFFER_INFO GetBufferInfo(bool throwOnNoConsole, out bool succeeded)
+        {
+            succeeded = false;
+            if (!(conOut == INVALID_HANDLE_VALUE))
+            {
+                CONSOLE_SCREEN_BUFFER_INFO console_SCREEN_BUFFER_INFO;
+                if (!GetConsoleScreenBufferInfo(conOut, out console_SCREEN_BUFFER_INFO))
+                {
+                    bool consoleScreenBufferInfo = GetConsoleScreenBufferInfo(GetStdHandle(-12), out console_SCREEN_BUFFER_INFO);
+                    if (!consoleScreenBufferInfo)
+                        consoleScreenBufferInfo = GetConsoleScreenBufferInfo(GetStdHandle(-10), out console_SCREEN_BUFFER_INFO);
+
+                    if (!consoleScreenBufferInfo)
+                        if (Marshal.GetLastWin32Error() == 6 && !throwOnNoConsole)
+                            return default(CONSOLE_SCREEN_BUFFER_INFO);
+                }
+                succeeded = true;
+                return console_SCREEN_BUFFER_INFO;
+            }
+            if (!throwOnNoConsole)
+                return default(CONSOLE_SCREEN_BUFFER_INFO);
+            throw new Exception("IO.IO_NoConsole");
+        }
+
+        private static void SetConsoleColor(bool isBackground, ConsoleColor c)
+        {
+            new UIPermission(UIPermissionWindow.SafeTopLevelWindows).Demand();
+            var color = ConsoleColorToColorAttribute((short)c, isBackground);
+            bool flag;
+            var bufferInfo = GetBufferInfo(false, out flag);
+            if (!flag) return;
+            var num = bufferInfo.wAttributes;
+            num &= (short)(isBackground ? -241 : -16);
+            num = (short)((ushort)num | (ushort)color);
+            SetConsoleTextAttribute(conOut, num);
+        }
+
+        private static ConsoleColor GetConsoleColor(bool isBackground)
+        {
+            bool flag;
+            var bufferInfo = GetBufferInfo(false, out flag);
+            if (!flag) return isBackground ? ConsoleColor.Black : ConsoleColor.Gray;
+            return ColorAttributeToConsoleColor((short)(bufferInfo.wAttributes & 240));
+        }
+
+        private static ConsoleColor ColorAttributeToConsoleColor(short c)
+        {
+            if ((short)(c & 255) != 0)
+                c >>= 4;
+            return (ConsoleColor)c;
+        }
+
+        internal static IntPtr conOut = IntPtr.Zero;
+
+        #endregion
+
+        #region Public
+
+        public static void ResetConsoleColor()
+        {
+            SetConsoleColor(true, ConsoleColor.Black);
+            SetConsoleColor(false, ConsoleColor.Gray);
+        }
+
+        public static ConsoleColor ForegroundColor
+        {
+            get
+            {
+                return GetConsoleColor(false);
+            }
+            set
+            {
+                SetConsoleColor(false, value);
+            }
+        }
+
+        public static ConsoleColor BackgroundColor
+        {
+            get
+            {
+                return GetConsoleColor(true);
+            }
+            set
+            {
+                SetConsoleColor(true, value);
+            }
+        }
+
+        #endregion
+    }
+}