123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- // --------------------------------------------------
- // UnityInjector - ConsoleWindow.cs
- // Copyright (c) Usagirei 2015 - 2015
- // --------------------------------------------------
- using System;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Text;
- using BepInEx.Configuration;
- namespace UnityInjector.ConsoleUtil
- {
- internal class ConsoleWindow
- {
- public static readonly ConfigEntry<bool> ConfigConsoleEnabled = ConfigFile.CoreConfig.AddSetting(
- "Logging.Console", "Enabled",
- false,
- "Enables showing a console for log output.");
- public static readonly ConfigEntry<bool> ConfigConsoleShiftJis = ConfigFile.CoreConfig.AddSetting(
- "Logging.Console", "ShiftJisEncoding",
- false,
- "If true, console is set to the Shift-JIS encoding, otherwise UTF-8 encoding.");
- public static bool IsAttached { get; private set; }
- private static IntPtr _cOut;
- private static IntPtr _oOut;
- public static TextWriter StandardOut { get; private set; }
- public static void Attach()
- {
- if (IsAttached)
- return;
- if (_oOut == IntPtr.Zero)
- _oOut = GetStdHandle(-11);
- // Store Current Window
- IntPtr currWnd = GetForegroundWindow();
- //Check for existing console before allocating
- if (GetConsoleWindow() == IntPtr.Zero)
- if (!AllocConsole())
- throw new Exception("AllocConsole() failed");
- // Restore Foreground
- SetForegroundWindow(currWnd);
- _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();
- IsAttached = true;
- }
- public static string Title
- {
- set
- {
- if (!IsAttached)
- return;
- if (value == null)
- {
- throw new ArgumentNullException(nameof(value));
- }
- if (value.Length > 24500)
- {
- throw new InvalidOperationException("Console title too long");
- }
- if (!SetConsoleTitle(value))
- {
- throw new InvalidOperationException("Console title invalid");
- }
- }
- }
- public static void Detach()
- {
- if (!IsAttached)
- return;
- if (!CloseHandle(_cOut))
- throw new Exception("CloseHandle() failed");
- _cOut = IntPtr.Zero;
- if (!FreeConsole())
- throw new Exception("FreeConsole() failed");
- if (!SetStdHandle(-11, _oOut))
- throw new Exception("SetStdHandle() failed");
- Init();
- IsAttached = false;
- }
- [DllImport("user32.dll")]
- private static extern IntPtr GetForegroundWindow();
- [DllImport("user32.dll")]
- [return: MarshalAs(UnmanagedType.Bool)]
- private static extern bool SetForegroundWindow(IntPtr hWnd);
- [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,
- uint desiredAccess,
- int shareMode,
- IntPtr securityAttributes,
- int creationDisposition,
- int flagsAndAttributes,
- IntPtr templateFile);
- [DllImport("kernel32.dll", SetLastError = false)]
- private static extern bool FreeConsole();
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern IntPtr GetStdHandle(int nStdHandle);
- private static void Init()
- {
- var stdOut = Console.OpenStandardOutput();
- StandardOut = new StreamWriter(stdOut, Encoding.Default)
- {
- AutoFlush = true
- };
- Console.SetOut(StandardOut);
- Console.SetError(StandardOut);
- }
- [DllImport("kernel32.dll", SetLastError = true)]
- private static extern bool SetStdHandle(int nStdHandle, IntPtr hConsoleOutput);
- [DllImport("kernel32.dll", BestFitMapping = true, CharSet = CharSet.Auto, SetLastError = true)]
- private static extern bool SetConsoleTitle(string title);
- }
- }
|