/// <summary> /// Launches the game. /// </summary> public void LaunchGame() { //start new process of the game executable try { // Do not move the argument assignment inside the gameStartInfo initializer. // It causes a TargetInvocationException crash through black magic. string gameArguments = string.Join(" ", ConfigHandler.GetGameArguments()); ProcessStartInfo gameStartInfo = new ProcessStartInfo { UseShellExecute = false, FileName = Config.GetGameExecutable(), Arguments = gameArguments }; this.GameExitArgs.GameName = Config.GetGameName(); Log.Info($"Launching game. \n\tExecutable path: {gameStartInfo.FileName}"); Process gameProcess = new Process { StartInfo = gameStartInfo, EnableRaisingEvents = true }; gameProcess.Exited += delegate { if (gameProcess.ExitCode != 0) { Log.Info($"The game exited with an exit code of {gameProcess.ExitCode}. " + "There may have been issues during runtime, or the game may not have started at all."); } this.GameExitArgs.ExitCode = gameProcess.ExitCode; OnGameExited(); // Manual disposing gameProcess.Dispose(); }; // Make sure the game executable is flagged as such on Unix if (SystemInformation.IsRunningOnUnix()) { Process.Start("chmod", $"+x {Config.GetGameExecutable()}"); } gameProcess.Start(); } catch (FileNotFoundException fex) { Log.Warn($"Game launch failed (FileNotFoundException): {fex.Message}"); Log.Warn("If the game executable is there, try overriding the executable name in the configuration file."); this.GameExitArgs.ExitCode = 2; OnGameLaunchFailed(); } catch (IOException ioex) { Log.Warn($"Game launch failed (IOException): {ioex.Message}"); this.GameExitArgs.ExitCode = 1; OnGameLaunchFailed(); } }