/// <summary> /// Starts the GTA process. /// </summary> private void StartGTAProcess() { Process process; ProcessProvider provider; provider = new ProcessProvider(); if (provider.GetGrandTheftAutoProcess() != null) { EventLogLogger.LogError("Unable to start the GTA V process as it is already running."); throw new ApplicationException("Unable to start the GTA V process as it is already running."); } if (_config.IsSteamGame) { string steamPath; steamPath = RegistryHelper.GetSteamPath(); if (!string.IsNullOrEmpty(steamPath)) { process = new Process(); process.StartInfo.FileName = $"{steamPath}\\Steam.exe"; process.StartInfo.Arguments = "-applaunch 271590 -StraightIntoFreemode"; process.Start(); } else { throw new ArgumentException("Unable to find the Steam installation path in the registry."); } } else { string installPath; installPath = RegistryHelper.GetGTASocialClubInstallPath(); if (!string.IsNullOrEmpty(installPath)) { process = new Process(); process.StartInfo.FileName = $"{installPath}\\PlayGTAV.exe"; process.StartInfo.Arguments = "-StraightIntoFreemode"; process.Start(); } else { throw new ArgumentException("Unable to find the PlayGTAV installation path in the registry."); } } }
/// <summary> /// Forcibly kills the GTA process and the associated launcher process. /// Throws argument exceptions if the process are unable to be found, /// or if they are still alive after being killed. /// </summary> private void KillGTAProcess() { Process process; Process launcherProcess; ProcessProvider provider; int timeout; provider = new ProcessProvider(); process = provider.GetGrandTheftAutoProcess(); timeout = 0; if (process != null) { process.Kill(); } else { throw new ApplicationException("Unable to locate GTA V process."); } do { // While the process has not exited, wait for a bit and then check again. // If we wait for a period of 30 seconds then exit out of the loop and // throw an exception because we do not want to end up in an infinite loop. Thread.Sleep(1000); timeout++; } while (!process.HasExited && (timeout < 30)); if (timeout >= 30) { // If we hit the timeout, throw an exception and log the error. throw new ApplicationException("Timed out trying to exit the GTA V process"); } // TODO: This is nasty, really nasty, but Rockstar can't program // a game properly so I guess this is what we're left with. The launcher process // acts as a giant try-catch statement around the entire of GTA, so if GTA crashes // or is killed by force, the launcher process will pop up with the usual 'safe mode' // message. // // The problem with this is that the launcher needs time to start up, as it seems as if // it sets a flag of some kind to tell itself that it has already prompted the user with // the 'safe mode' warning message. If the launcher process never has time to initialize when // the game is killed, then it never gets to set the flag to say it warned the user. // As a result of this, the next time the game is started, because it relies on the launcher // process to instance the game, it will show up the 'safe mode' dialog and stop us from // launching the game until the dialog is dealt with. Thread.Sleep(5000); // Get the launcher process, this is needed because GTA is special and will try to // catch all exceptions that occur, and pop up an annoying 'Safe Mode' dialog. This is // annoying and useless, we have no other way to stop GTA quickly other than a force // quit so this dialog is expected. If we find it, kill it. It serves no purpose for us. launcherProcess = provider.GetGrandTheftAutoLauncherProcess(); if (launcherProcess != null) { launcherProcess.Kill(); } }