Files
BepInEx/BepInEx.Core/Console/Windows/ConsoleWindow.cs
T
2020-11-05 23:18:52 +11:00

130 lines
3.4 KiB
C#

// --------------------------------------------------
// UnityInjector - ConsoleWindow.cs
// Copyright (c) Usagirei 2015 - 2015
// --------------------------------------------------
using System;
using System.Runtime.InteropServices;
using BepInEx;
namespace UnityInjector.ConsoleUtil
{
internal class ConsoleWindow
{
public static bool IsAttached { get; private set; }
public static IntPtr ConsoleOutHandle;
public static IntPtr OriginalStdoutHandle;
public static void Attach()
{
if (IsAttached)
return;
if (OriginalStdoutHandle == IntPtr.Zero)
OriginalStdoutHandle = 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);
ConsoleOutHandle = CreateFile("CONOUT$", 0x80000000 | 0x40000000, 2, IntPtr.Zero, 3, 0, IntPtr.Zero);
BepInEx.ConsoleUtil.Kon.conOut = ConsoleOutHandle;
if (!SetStdHandle(-11, ConsoleOutHandle))
throw new Exception("SetStdHandle() failed");
if (OriginalStdoutHandle != IntPtr.Zero && ConsoleManager.ConfigConsoleOutRedirectType.Value == ConsoleManager.ConsoleOutRedirectType.ConsoleOut)
CloseHandle(OriginalStdoutHandle);
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(ConsoleOutHandle))
throw new Exception("CloseHandle() failed");
ConsoleOutHandle = IntPtr.Zero;
if (!FreeConsole())
throw new Exception("FreeConsole() failed");
if (!SetStdHandle(-11, OriginalStdoutHandle))
throw new Exception("SetStdHandle() failed");
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);
[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);
}
}