[bugfix] Start BS as Admin when Steam is running as admin but BSM is not

This commit is contained in:
MathieuG-P
2024-01-20 15:42:30 +01:00
parent 444db56d90
commit 4c8617a419
15 changed files with 725 additions and 21 deletions
+13 -1
View File
@@ -10,4 +10,16 @@ export async function taskRunning(task: string): Promise<boolean> {
log.error(error);
return false;
}
}
}
export async function getProcessPid(task: string): Promise<number> {
try {
const processes = await psList();
const process = processes.find(process => process.name?.includes(task) || process.cmd?.includes(task));
return process?.pid;
}
catch(error){
log.error(error);
return null;
}
}
@@ -8,6 +8,9 @@ import { BS_APP_ID, BS_EXECUTABLE, STEAMVR_APP_ID } from "../../constants";
import log from "electron-log";
import { AbstractLauncherService } from "./abstract-launcher.service";
import { CustomError } from "../../../shared/models/exceptions/custom-error.class";
import isElevated from "is-elevated";
import { UtilsService } from "../utils.service";
import { exec } from "child_process";
export class SteamLauncherService extends AbstractLauncherService implements StoreLauncherInterface{
@@ -21,10 +24,12 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
}
private readonly steam: SteamService;
private readonly util: UtilsService;
private constructor(){
super();
this.steam = SteamService.getInstance();
this.util = UtilsService.getInstance();
}
private getSteamVRPath(): Promise<string> {
@@ -41,6 +46,17 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
});
}
private needStartBsAsAdmin(): Promise<boolean> {
return isElevated().then(elevated => {
if(elevated){ return false; }
return this.steam.isElevated();
})
}
private getStartBsAsAdminExePath(): string {
return path.join(this.util.getAssetsScriptsPath(), "start_beat_saber_admin.exe");
}
public async restoreSteamVR(): Promise<void> {
const steamVrFolder = await this.getSteamVRPath();
const steamVrBackup = `${steamVrFolder}.bak`;
@@ -53,7 +69,7 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
log.error("Error while restoring SteamVR", err);
});
}
public launch(launchOptions: LaunchOption): Observable<BSLaunchEventData>{
return new Observable<BSLaunchEventData>(obs => {(async () => {
@@ -90,7 +106,26 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
obs.next({type: BSLaunchEvent.BS_LAUNCHING});
await this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} }).then(exitCode => {
const needToStartAsAdmin = await this.needStartBsAsAdmin().catch(err => {
log.error("Error while checking if need to start BS as Admin", err);
return false;
});
const launchPromise = !needToStartAsAdmin ? (
this.launchBs(exePath, launchArgs, { env: {...process.env, "SteamAppId": BS_APP_ID} })
) : (
new Promise<number>(resolve => {
const adminProcess = exec(`"${this.getStartBsAsAdminExePath()}" "${exePath}" ${launchArgs.join(" ")}`, { env: {...process.env, "SteamAppId": BS_APP_ID} });
adminProcess.on("error", err => {log.error("Error while starting BS as Admin", err); resolve(-1)});
setTimeout(() => {
adminProcess.removeAllListeners("error");
resolve(-1);
}, 35_000);
})
);
await launchPromise.then(exitCode => {
log.info("BS process exit code", exitCode);
}).catch(err => {
throw CustomError.fromError(err, BSLaunchError.BS_EXIT_ERROR);
@@ -109,4 +144,4 @@ export class SteamLauncherService extends AbstractLauncherService implements Sto
})});
}
}
}
+22 -5
View File
@@ -5,11 +5,15 @@ import { readFile } from "fs/promises";
import { pathExist } from "../helpers/fs.helpers";
import log from "electron-log";
import { app, shell } from "electron";
import { taskRunning } from "../helpers/os.helpers";
import { getProcessPid, taskRunning } from "../helpers/os.helpers";
import { isElevated } from "query-process";
export class SteamService {
private static readonly PROCESS_NAME = "steam";
private static instance: SteamService;
private steamPath: string = '';
private constructor(){}
@@ -29,12 +33,25 @@ export class SteamService {
}
public async steamRunning(): Promise<boolean>{
const steamProcessRunning = await taskRunning("steam");
const steamProcessRunning = await taskRunning(SteamService.PROCESS_NAME);
if(process.platform === "linux") { return steamProcessRunning; }
const activeUser = await this.getActiveUser().catch(err => log.error(err));
return steamProcessRunning && !!activeUser;
}
public async getSteamPid(): Promise<number>{
return getProcessPid(SteamService.PROCESS_NAME);
}
public async isElevated(): Promise<boolean>{
if(process.platform === "linux"){ return true; }
const steamPid = await this.getSteamPid();
if(!steamPid){ return false; }
return isElevated(steamPid);
}
public async getSteamPath(): Promise<string>{
if(this.steamPath){ return this.steamPath; }
@@ -68,7 +85,7 @@ export class SteamService {
let libraryFolders: any = path.join(steamPath, "steamapps", "libraryfolders.vdf");
if (!(await pathExist(libraryFolders))) { return null; }
libraryFolders = parse(await readFile(libraryFolders, { encoding: "utf-8" }));
if (!libraryFolders.libraryfolders) { return null; }
@@ -83,7 +100,7 @@ export class SteamService {
}
return null;
} catch (e) {
log.error(e);
return null;
@@ -91,7 +108,7 @@ export class SteamService {
}
public async openSteam(): Promise<void> {
await shell.openPath("steam://open/games");
return new Promise((resolve, reject) => {