Skip to content

Game.WinConsole

Assembly: Assembly-CSharp
Namespace: Game.Debug

Type: internal static class

Base: System.Object

Summary: This helper class manages a Windows console for the game process. It can attach to the parent process console or allocate a new console and redirects .NET Console streams (Console.Out, Console.Error and Console.In) to the native console handles (CONOUT$, CONIN$). It uses P/Invoke to call kernel32 functions (AllocConsole, AttachConsole, CreateFileW) and creates FileStream wrappers around console handles to set up StreamWriter/StreamReader redirection. This is Windows-only and requires the game to run with permissions that allow calling these Win32 APIs.


Fields

  • private const uint GENERIC_WRITE
    This constant (0x40000000) is the Win32 GENERIC_WRITE access mask used when opening CONOUT$.

  • private const uint GENERIC_READ
    This constant (0x80000000) is the Win32 GENERIC_READ access mask used when opening CONIN$.

  • private const uint FILE_SHARE_READ
    Win32 FILE_SHARE_READ (0x1) share mode.

  • private const uint FILE_SHARE_WRITE
    Win32 FILE_SHARE_WRITE (0x2) share mode.

  • private const uint OPEN_EXISTING
    Win32 OPEN_EXISTING (0x3) creation disposition used for console file names.

  • private const uint FILE_ATTRIBUTE_NORMAL
    Win32 FILE_ATTRIBUTE_NORMAL (0x80) attribute flag.

  • private const uint ERROR_ACCESS_DENIED
    Win32 error code for access denied (0x5). Used to check AttachConsole failure reason.

  • private const uint ATTACH_PARRENT
    Value set to uint.MaxValue (0xFFFFFFFF) used when calling AttachConsole to attach to the parent process console.

Properties

  • None. (This is a static helper class and exposes no properties.)

Constructors

  • No public or instance constructors.
    Because WinConsole is declared static, it cannot be instantiated and does not expose constructors.

Methods

  • public static void Initialize(bool alwaysCreateNewConsole = true)
    Initializes a console for the current process. If alwaysCreateNewConsole is true, the method attempts to allocate a new console via AllocConsole(). If false, it first attempts to attach to the parent process console via AttachConsole(ATTACH_PARRENT). If attaching fails for a reason other than access denied, the code will allocate a new console. After a successful attach/alloc, the method calls into InitializeOutStream() to redirect Console.Out and Console.Error.

  • private static void InitializeOutStream()
    Creates a FileStream for "CONOUT$" and wraps it in a StreamWriter (AutoFlush = true). Then sets Console.SetOut and Console.SetError to that writer so that console output and error write to the native console. If creating the stream fails, no redirection is performed.

  • private static void InitializeInStream()
    Creates a FileStream for "CONIN$" and wraps it in a StreamReader, then sets Console.SetIn to that reader so that Console.Read* APIs read from the native console. Note: this method is private and is not called by Initialize() in the current implementation; it can be enabled if input is required.

  • private static FileStream CreateFileStream(string name, uint win32DesiredAccess, uint win32ShareMode, FileAccess dotNetFileAccess)
    Opens a native file handle to the given console special filename (e.g., "CONOUT$", "CONIN$") by calling CreateFileW. The raw handle is wrapped in a SafeFileHandle (ownsHandle: true). If the handle is valid, it returns a FileStream constructed from that SafeFileHandle using the provided FileAccess; otherwise returns null. This encapsulates P/Invoke handle creation and maps it into a managed stream.

  • private static extern int AllocConsole() (P/Invoke)
    Calls kernel32 AllocConsole to allocate a new console for the calling process.

  • private static extern uint AttachConsole(uint dwProcessId) (P/Invoke)
    Calls kernel32 AttachConsole to attach the calling process to the console of another process (or the parent when dwProcessId == ATTACH_PARRENT).

  • private static extern IntPtr CreateFileW(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile) (P/Invoke)
    Win32 CreateFileW used to open the special console files CONIN$ and CONOUT$.

Notes and caveats: - Windows-only: the class uses kernel32 P/Invoke and will not work on non-Windows platforms. - Permission/hosting environment: calling these APIs may fail under restricted environments (e.g., sandboxes, certain service contexts or when running as a Steam background process). AttachConsole can fail with ERROR_ACCESS_DENIED if the parent process is not attachable. - Stream creation returns null on failure; callers should handle absence of console redirection gracefully. - Initialize() currently only calls InitializeOutStream() when console is successfully allocated/attached; InitializeInStream() is available but not invoked automatically.

Usage Example

// Typical usage from mod startup or game initialization code:
public override void OnCreated() // or similar initialization hook
{
    // Try to attach to parent console; if not available, create a new one.
    WinConsole.Initialize(alwaysCreateNewConsole: true);

    // After Initialize, Console.WriteLine / Console.Error will print to the Windows console.
    Console.WriteLine("Console initialized for debugging output.");
}