From 4e48fe197e26c7a07a27ba1fe7be00bf9c202e2d Mon Sep 17 00:00:00 2001 From: Meivyn <793322+Meivyn@users.noreply.github.com> Date: Fri, 19 May 2023 13:22:34 -0400 Subject: [PATCH] Allow console attachment to a specific PID --- IPA.Injector/Injector.cs | 31 +++++++++++++++++++++++------ IPA.Loader/Logging/ConsoleWindow.cs | 7 +++---- docs/articles/command-line.md | 21 +++++++++++-------- 3 files changed, 41 insertions(+), 18 deletions(-) diff --git a/IPA.Injector/Injector.cs b/IPA.Injector/Injector.cs index 1ea7e058..401e9f71 100644 --- a/IPA.Injector/Injector.cs +++ b/IPA.Injector/Injector.cs @@ -43,8 +43,8 @@ namespace IPA.Injector try { - if (Environment.GetCommandLineArgs().Contains("--verbose")) - WinConsole.Initialize(); + var arguments = Environment.GetCommandLineArgs(); + MaybeInitializeConsole(arguments); SetupLibraryLoading(); @@ -63,8 +63,8 @@ namespace IPA.Injector // this is weird, but it prevents Mono from having issues loading the type. // IMPORTANT: NO CALLS TO ANY LOGGER CAN HAPPEN BEFORE THIS var unused = StandardLogger.PrintFilter; - #region // Above hack explaination - /* + #region // Above hack explanation + /* * Due to an unknown bug in the version of Mono that Unity uses, if the first access to StandardLogger * is a call to a constructor, then Mono fails to load the type correctly. However, if the first access is to * the above static property (or maybe any, but I don't really know) it behaves as expected and works fine. @@ -73,7 +73,7 @@ namespace IPA.Injector log.Debug("Initializing logger"); - SelfConfig.ReadCommandLine(Environment.GetCommandLineArgs()); + SelfConfig.ReadCommandLine(arguments); SelfConfig.Load(); DisabledConfig.Load(); @@ -106,6 +106,25 @@ namespace IPA.Injector } } + private static void MaybeInitializeConsole(string[] arguments) + { + var i = 0; + while (i < arguments.Length) + { + if (arguments[i++] == "--verbose") + { + if (i == arguments.Length) + { + WinConsole.Initialize(WinConsole.AttachParent); + return; + } + + WinConsole.Initialize(int.TryParse(arguments[i], out int processId) ? processId : WinConsole.AttachParent); + return; + } + } + } + private static void EnsureDirectories() { string path; @@ -260,7 +279,7 @@ namespace IPA.Injector using var ascModule = VirtualizedModule.Load(ascPath); ascModule.Virtualize(cAsmName, () => bkp?.Add(ascPath)); } - catch (Exception e) + catch (Exception e) { injector.Error($"Could not virtualize {ascPath}"); if (SelfConfig.Debug_.ShowHandledErrorStackTraces_) diff --git a/IPA.Loader/Logging/ConsoleWindow.cs b/IPA.Loader/Logging/ConsoleWindow.cs index 648fd73e..5284b201 100644 --- a/IPA.Loader/Logging/ConsoleWindow.cs +++ b/IPA.Loader/Logging/ConsoleWindow.cs @@ -22,10 +22,10 @@ namespace IPA.Logging internal static bool IsInitialized; - public static void Initialize(bool alwaysCreateNewConsole = false) + public static void Initialize(int processId, bool alwaysCreateNewConsole = false) { bool consoleAttached; - if (alwaysCreateNewConsole || !(consoleAttached = AttachConsole(AttachParent))) + if (alwaysCreateNewConsole || !(consoleAttached = AttachConsole(processId))) { consoleAttached = AllocConsole(); } @@ -132,9 +132,8 @@ namespace IPA.Logging private const uint FileShareWrite = 0x00000002; private const uint OpenExisting = 0x00000003; private const uint FileAttributeNormal = 0x80; - private const uint ErrorAccessDenied = 5; - private const int AttachParent = -1; + internal const int AttachParent = -1; #endregion } diff --git a/docs/articles/command-line.md b/docs/articles/command-line.md index ea3e846c..da9cce06 100644 --- a/docs/articles/command-line.md +++ b/docs/articles/command-line.md @@ -26,6 +26,16 @@ Here's a quick list of what they are and what they do. > Makes a console appear with log information at startup. > + > Optionally, an explicit process ID can be specified to start the game with an external console. This allows it to be + > launched via Steam without being interrupted by its "Allow game launch?" if launched directly from the `.exe`. + > + > Example for Beat Saber using PowerShell: + > + > ``` + > .\steam.exe -applaunch 620980 --verbose $PID + > ``` + > + > Do note that this isn't going to work from an elevated terminal. - `--debug` @@ -35,15 +45,13 @@ Here's a quick list of what they are and what they do. > This option also forces BSIPA to show all debug messages in the console, as well as where they were called. > > This overrides the config settings `Debug.ShowDebug` and `Debug.ShowCallSource`. - > - `--trace` - + > Enables trace level messages. By default, they do not ever enter the message queue, and thus cost almost nothing. > When this or the config option is used, they are added and logged with the same rules as Debug messages. > > This overrides the config setting `Debug.ShowTrace`. - > - `--mono-debug` @@ -53,7 +61,6 @@ Here's a quick list of what they are and what they do. > debugger server running on port 10000 on `localhost`. > > Implies `--debug`. - > - `--server` @@ -62,7 +69,6 @@ Here's a quick list of what they are and what they do. > When paired with `--mono-debug`, this option makes the Mono soft debugger act in server mode. It begins listening on > port 10000 on any address, and will pause startup (with no window) until a debugger is connected. I recommend using > SDB, but that is a command line debugger and a lot of people don't care for those. - > - `--no-yeet` @@ -73,7 +79,6 @@ Here's a quick list of what they are and what they do. > behaviour is disabled. > > Overrides the config setting `YeetMods`. - > - `--condense-logs` @@ -85,11 +90,11 @@ Here's a quick list of what they are and what they do. > Overrides the config setting `Debug.CondenseModLogs`. - `--plugin-logs` - + > Causes each plugins' log messages to be written to files in their own folder for ease of debugging. > > This was the default through 4.1.6, however is now disabled by default. > > Overrides the config setting `Debug.CreateModLogs`. - + ***