From 482d8abd6dd9226a12e2cf0f2a9de935ca137f79 Mon Sep 17 00:00:00 2001 From: Roka Date: Tue, 21 Oct 2025 21:11:37 -0400 Subject: [PATCH] Fix process detection bugs and resource leaks in AppApiElectron (GameHandler.cs) (#1444) * Fix process detection and resource leaks Critical bugs: - Fix VRChat detection by removing .exe from process name Performance: - Use GetProcessesByName() to avoid scanning all processes - Optimize IsSteamVRRunning to check exact matches first Resource management: - Add Process.Dispose() calls to prevent handle leaks - Standardize on Dispose() instead of Close() * Fix broken ExitCode check in StartGame Remove ExitCode check that always threw an exception. You cannot access Process.ExitCode on a process that is still running~ it throws InvalidOperationException. Steam stays running after starting VRChat, so this check always failed. Simplified to return true when Process.Start() succeeds, since Steam handles VRChat launch asynchronously and there's no way to verify immediate success. Also changed Close() to Dispose() for consistency. --- Dotnet/AppApi/Electron/GameHandler.cs | 54 ++++++++++++++++----------- 1 file changed, 32 insertions(+), 22 deletions(-) diff --git a/Dotnet/AppApi/Electron/GameHandler.cs b/Dotnet/AppApi/Electron/GameHandler.cs index 866a2a06..6e9c73dc 100644 --- a/Dotnet/AppApi/Electron/GameHandler.cs +++ b/Dotnet/AppApi/Electron/GameHandler.cs @@ -31,32 +31,44 @@ namespace VRCX public override bool IsGameRunning() { - var isGameRunning = false; - var processes = Process.GetProcesses(); + var processes = Process.GetProcessesByName("VRChat"); + var isGameRunning = processes.Length > 0; + foreach (var process in processes) - { - if (process.ProcessName == "VRChat.exe") - { - isGameRunning = true; - break; - } - } + process.Dispose(); return isGameRunning; } public override bool IsSteamVRRunning() { - var isSteamVRRunning = false; - var processes = Process.GetProcesses(); - foreach (var process in processes) + // Check exact matches (fast - no full process scan needed) + var processNames = new[] { "vrmonitor", "monado-service" }; + foreach (var name in processNames) { - if (process.ProcessName == "vrmonitor" || process.ProcessName == "monado-service" || process.ProcessName.EndsWith("wivrn-server")) + var processes = Process.GetProcessesByName(name); + var isSteamVRRunning = processes.Length > 0; + + foreach (var process in processes) + process.Dispose(); + if (isSteamVRRunning) + return true; + } + + // Check for wivrn-server (requires full scan) + var allProcesses = Process.GetProcesses(); + var isRunning = false; + foreach (var process in allProcesses) + { + if (process.ProcessName.EndsWith("wivrn-server")) { - isSteamVRRunning = true; + isRunning = true; break; } } - return isSteamVRRunning; + + foreach (var process in allProcesses) + process.Dispose(); + return isRunning; } public override int QuitGame() @@ -65,6 +77,8 @@ namespace VRCX if (processes.Length == 1) processes[0].Kill(); + foreach (var process in processes) + process.Dispose(); return processes.Length; } @@ -78,12 +92,8 @@ namespace VRCX Arguments = $"-applaunch 438100 {arguments}", UseShellExecute = false, }); - if (process?.ExitCode == 0) - { - process.Close(); - return true; - } - process?.Close(); + process?.Dispose(); + return true; // Steam accepted launch command (no exception thrown) } catch (Exception e) { @@ -111,7 +121,7 @@ namespace VRCX FileName = steamExecutable, Arguments = $"-applaunch 438100 {arguments}", UseShellExecute = false, - })?.Close(); + })?.Dispose(); return true; }