Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/terminal-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ interface ShellSpawnConfig {
executable: string;
args: string[];
useShellOption: string | boolean;
// When true, pass args verbatim on Windows (see executeCommand). Only cmd.exe
// needs this; its quote parsing conflicts with libuv's default \" escaping.
windowsVerbatim?: boolean;
}

/**
Expand Down Expand Up @@ -103,6 +106,7 @@ function getShellSpawnArgs(shellPath: string, command: string): ShellSpawnConfig
return {
executable: shellPath,
args: ['/c', command],
windowsVerbatim: true,
useShellOption: false
};
}
Expand Down Expand Up @@ -222,6 +226,17 @@ export class TerminalManager {
spawnOptions.env.PATHEXT = getRepairedPathExt();
}

// On Windows, when we invoke cmd.exe directly and pass the user's command as a
// single argument, Node/libuv applies MSVCRT-style quoting that escapes embedded
// double quotes as \" . cmd.exe does not understand that escaping, so any command
// containing quotes (e.g. a quoted path with spaces like "C:\Program Files\app.exe")
// is corrupted before the shell ever parses it. Passing arguments verbatim lets
// cmd handle its own quoting. Scoped to shells that set windowsVerbatim (cmd only)
// because PowerShell/pwsh have different quote rules and must NOT use verbatim.
if (process.platform === 'win32' && spawnConfig.windowsVerbatim) {
spawnOptions.windowsVerbatimArguments = true;
}

// Spawn the process with appropriate arguments
const childProcess = spawn(spawnConfig.executable, spawnConfig.args, spawnOptions);
let output = '';
Expand Down
Loading