fix(subprocess): honor Windows environment key casing

This commit is contained in:
Tianyi Cui
2026-07-29 04:19:04 +08:00
parent 03f1c8eb43
commit 3537665806
2 changed files with 13 additions and 3 deletions

View File

@@ -102,9 +102,9 @@ export class LocalSubprocessService extends SubprocessService {
}
private executableCandidates(command: string, env: NodeJS.ProcessEnv): string[] {
const path = env.PATH ?? ''
const path = environmentValue(env, 'PATH') ?? ''
const extensions = process.platform === 'win32' && extname(command) === ''
? (env.PATHEXT ?? '.COM;.EXE;.BAT;.CMD').split(';')
? (environmentValue(env, 'PATHEXT') ?? '.COM;.EXE;.BAT;.CMD').split(';')
: ['']
return path.split(delimiter).flatMap(directory =>
directory === '' ? [] : extensions.map(extension => resolve(this.cwd, directory, command + extension)))
@@ -156,4 +156,12 @@ export class LocalSubprocessService extends SubprocessService {
}
}
/** Read a Windows environment key using the platform's case-insensitive semantics. */
function environmentValue(env: NodeJS.ProcessEnv, name: 'PATH' | 'PATHEXT'): string | undefined {
const exact = env[name]
if (exact !== undefined || process.platform !== 'win32') return exact
const normalized = name.toUpperCase()
return Object.entries(env).find(([key]) => key.toUpperCase() === normalized)?.[1]
}
export default LocalSubprocessService

View File

@@ -62,8 +62,10 @@ describe('LocalSubprocessService', () => {
}).executableCandidates.bind(service)
const platform = vi.spyOn(process, 'platform', 'get').mockReturnValue('win32')
try {
expect(candidates('tool', { PATH: `${delimiter}/bin`, PATHEXT: '.EXE;.CMD' }))
expect(candidates('tool', { Path: `${delimiter}/bin`, PathExt: '.EXE;.CMD' }))
.toEqual(['/bin/tool.EXE', '/bin/tool.CMD'])
expect(candidates('tool', { Path: '/ambient', PATH: '/explicit', PATHEXT: '.EXE' }))
.toEqual(['/explicit/tool.EXE'])
expect(candidates('tool.exe', {})).toEqual([])
expect(candidates('tool', { PATH: '/bin' })).toHaveLength(4)
} finally {