Skip to content

Commit

Permalink
callRunner: Use PowerShell to run commands on Windows
Browse files Browse the repository at this point in the history
PowerShell's `Start-Process` cmdlet & its `-Wait` parameter are used to wait
for a process tree to exit. This means we can now accurately track the "Playing"
 status of games on Windows.
  • Loading branch information
CommandMC committed Nov 7, 2023
1 parent 75c72c4 commit f806f30
Showing 1 changed file with 39 additions and 7 deletions.
46 changes: 39 additions & 7 deletions src/backend/launcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
flatPakHome,
isLinux,
isMac,
isWindows,
isSteamDeckGameMode,
runtimePath,
userHome
Expand Down Expand Up @@ -862,13 +863,32 @@ async function callRunner(
runner: RunnerProps,
options?: CallRunnerOptions
): Promise<ExecResult> {
const fullRunnerPath = join(runner.dir, runner.bin)
const appName = commandParts[commandParts.findIndex(() => 'launch') + 1]

// Necessary to get rid of possible undefined or null entries, else
// TypeError is triggered
commandParts = commandParts.filter(Boolean)

let bin = runner.bin
let fullRunnerPath = join(runner.dir, bin)

// On Windows: Use PowerShell's `Start-Process` to wait for the process and
// its children to exit
if (isWindows) {
const argsAsString = commandParts
.map((part) => (part.includes(' ') ? `"\`"${part}\`""` : `"${part}"`))
.join(',')
commandParts = [
'Start-Process',
`${fullRunnerPath}`,
'-Wait',
'-ArgumentList',
argsAsString,
'-NoNewWindow'
]
bin = fullRunnerPath = 'powershell'
}

const safeCommand = getRunnerCallWithoutCredentials(
[...commandParts],
options?.env,
Expand Down Expand Up @@ -897,8 +917,6 @@ async function callRunner(
}
}

const bin = runner.bin

// check if the same command is currently running
// if so, return the same promise instead of running it again
const key = [runner.name, commandParts].join(' ')
Expand Down Expand Up @@ -1055,11 +1073,25 @@ function getRunnerCallWithoutCredentials(
const modifiedCommand = [...command]
// Redact sensitive arguments (Authorization Code for Legendary, token for GOGDL)
for (const sensitiveArg of ['--code', '--token']) {
const sensitiveArgIndex = modifiedCommand.indexOf(sensitiveArg)
if (sensitiveArgIndex === -1) {
continue
// PowerShell's argument formatting is quite different, instead of having
// arguments as members of `command`, they're all in one specific member
// (the one after "-ArgumentList")
if (runnerPath === 'powershell') {
const argumentListIndex = modifiedCommand.indexOf('-ArgumentList') + 1
if (!argumentListIndex) continue
modifiedCommand[argumentListIndex] = modifiedCommand[
argumentListIndex
].replace(
new RegExp(`"${sensitiveArg}","(.*?)"`),
`"${sensitiveArg}","<redacted>"`
)
} else {
const sensitiveArgIndex = modifiedCommand.indexOf(sensitiveArg)
if (sensitiveArgIndex === -1) {
continue
}
modifiedCommand[sensitiveArgIndex + 1] = '<redacted>'
}
modifiedCommand[sensitiveArgIndex + 1] = '<redacted>'
}

const formattedEnvVars: string[] = []
Expand Down

0 comments on commit f806f30

Please sign in to comment.