mirror of
https://github.com/BepInEx/BepInEx.git
synced 2026-10-20 01:46:13 +00:00
123 lines
4.2 KiB
C#
123 lines
4.2 KiB
C#
// --------------------------------------------------
|
|
// UnityInjector - ConsoleWindow.cs
|
|
// Copyright (c) Usagirei 2015 - 2015
|
|
// --------------------------------------------------
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using BepInEx;
|
|
using BepInEx.ConsoleUtil;
|
|
|
|
namespace UnityInjector.ConsoleUtil
|
|
{
|
|
internal class ConsoleWindow
|
|
{
|
|
public static IntPtr ConsoleOutHandle;
|
|
public static IntPtr OriginalStdoutHandle;
|
|
public static bool IsAttached { get; private set; }
|
|
|
|
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 Attach()
|
|
{
|
|
if (IsAttached)
|
|
return;
|
|
|
|
if (OriginalStdoutHandle == IntPtr.Zero)
|
|
OriginalStdoutHandle = GetStdHandle(-11);
|
|
|
|
// Store Current Window
|
|
var 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);
|
|
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 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);
|
|
}
|
|
}
|