vscode-cpptools
vscode-cpptools copied to clipboard
externalTerminal console does not launch when path includes spaces
Type: Bug
- Create a debug launch configuration that uses the
externalTerminalconsole type and make it the currently selected debug configuration. - Launch the debugger.
- An external window will appear with an error message similar to this (note the quoting of path elements with spaces):
[error 2147942402 (0x80070002) when launching `Lins\AppData\Local\Microsoft\WindowsApps\wt.exe
-d C:\WINDOWS\System32\cmd.exe /c c:\Users\Adam "Lins\.vscode\extensions\ms-vscode.cpptools-1.18.5-win32-x64\debugAdapters\vsdbg\bin\VsDebugConsole.exe
\\.\pipe\Microsoft-VisualStudio-Debug-Console-{4378F327-15AB-4D47-BC0B-45CB6D2FF806}
Local\{4378F327-15AB-4D47-BC0B-45CB6D2FF806} /AutoExit & pause"']
- In VSCode, the debug control panel will appear as well as an error message pop-up noting that the target application cannot be started.
Extension version: 1.18.5 VS Code version: Code 1.86.1 (31c37ee8f63491495ac49e43b8544550fbae4533, 2024-02-07T09:08:20.941Z) OS version: Windows_NT x64 10.0.22631 Modes:
System Info
| Item | Value |
|---|---|
| CPUs | 12th Gen Intel(R) Core(TM) i7-1265U (12 x 2688) |
| GPU Status | 2d_canvas: enabled canvas_oop_rasterization: enabled_on direct_rendering_display_compositor: disabled_off_ok gpu_compositing: enabled multiple_raster_threads: enabled_on opengl: enabled_on rasterization: enabled raw_draw: disabled_off_ok skia_graphite: disabled_off video_decode: enabled video_encode: enabled vulkan: disabled_off webgl: enabled webgl2: enabled webgpu: enabled |
| Load (avg) | undefined |
| Memory (System) | 15.44GB (5.34GB free) |
| Process Argv | ..\..\.local\tenpo.code-workspace --crash-reporter-id 0312ea16-4d0d-401e-92c7-0bd47ce3b3fd |
| Screen Reader | no |
| VM | 0% |
A/B Experiments
vsliv368cf:30146710
vspor879:30202332
vspor708:30202333
vspor363:30204092
vswsl492:30256859
vscod805:30301674
binariesv615:30325510
vsaa593cf:30376535
py29gd2263:30899288
c4g48928:30535728
azure-dev_surveyone:30548225
2i9eh265:30646982
962ge761:30959799
pythongtdpath:30769146
welcomedialogc:30910334
pythonidxpt:30866567
pythonnoceb:30805159
asynctok:30898717
pythontestfixt:30902429
pythonregdiag2:30936856
pyreplss1:30897532
pythonmypyd1:30879173
pythoncet0:30885854
pythontbext0:30879054
accentitlementsc:30887149
dsvsc016:30899300
dsvsc017:30899301
dsvsc018:30899302
b5d27386:30958190
a89i1917:30961429
3ef8e399:30964150
e3gdj431:30958358
Have you attempted to launch the console with a path that doesn't include spaces? This may be due to our shell quoting logic as it should be applying shell quoting to your arguments whenever a special character is present such as a space or backslash.
I first noticed this issue after changing laptops, which also migrated me from Windows 10 to Windows 11. My %USERPROFILE% path on Windows 10 didn't have a space in it; on Windows 11, it does.
I don't think I can (safely) change my user account folder to remove the space or add a new user to this machine. Which makes it hard to test launching the debugger with an external terminal using a profile that doesn't have a space in the path.
Ok, given that context, I believe this may be the result of a VS Code Bug: https://github.com/microsoft/vscode/issues/204039
This should be fixed if you download the latest VS Code Insiders. Could you give that a try? https://code.visualstudio.com/insiders/
I tried v1.87.0-insider with the same result: the space in the %USERPROFILE% path isn't being handled correctly, causing a debug session with console type externalTerminal to fail.
Version: 1.87.0-insider (user setup) Commit: e587755905208e47725c5196539c4ca898255fe6 Date: 2024-02-15T05:47:14.979Z Electron: 27.3.2 ElectronBuildId: 26836302 Chromium: 118.0.5993.159 Node.js: 18.17.1 V8: 11.8.172.18-electron.0 OS: Windows_NT x64 10.0.22631
This issue is still happening on Windows 10 in v1.88.1 of vscode with v1.19.9 of cpptools.
This launch config:
{
"type": "cppvsdbg",
"name": "Run (Debug)",
"request": "launch",
"program": "${workspaceFolder}/build/Debug/bin/AppName.exe",
"stopAtEntry": false,
"cwd": "${workspaceFolder}/dev",
"environment": [],
"console": "externalTerminal",
"preLaunchTask": "Build Debug"
}
results in this error when the user folder has a space in the name:
[error 2147942402 (0x80070002) when launching `LastName\AppData\Local\Microsoft\WindowsApps\wt.exe -d . C:\Windows\System32\cmd.exe /c "c:\Users\FirstName LastName\.vscode\extensions\ms-vscode.cpptools-1.19.9-win32-x64\debugAdapters\vsdbg\bin\VsDebugConsole.exe" \\.\pipe\Microsoft-VisualStudio-Debug-Console-{586864FF-B80E-4F29-9E79-2B32A189984F} Local\{586864FF-B80E-4F29-9E79-2B32A189984F} /AutoExit & pause']
TL;DR: Workarounds:
-
Option 1 (recommended): Set
Terminal > External: Windows Exectowt -
Option 2: Change
consolefromexternalTerminaltointernalConsole
I am getting the same error:
[error 2147942402 (0x80070002) when launching `Livingston\AppData\Local\Microsoft\WindowsApps\wt.exe -d . C:\WINDOWS\System32\cmd.exe /c "c:\Users\Daniel Livingston.vscode\extensions\ms-vscode.cpptools-1.19.9-win32-x64\debugAdapters\vsdbg\bin\VsDebugConsole.exe" \.\pipe\Microsoft-VisualStudio-Debug-Console-{C4B324D0-B6B6-4ECF-89D6-2BE2737ED7E1} Local{C4B324D0-B6B6-4ECF-89D6-2BE2737ED7E1} /AutoExit & pause']
The path should be 'C:\Users\Daniel Livingston\AppData\Local\Microsoft\WindowsApps\wt.exe'.
I'm pretty sure things are going wrong in vscode/src/vs/platform/externalTerminal/node/externalTerminalService.ts:
public async runInTerminal(title: string, dir: string, args: string[], envVars: ITerminalEnvironment, settings: IExternalTerminalSettings): Promise<number | undefined> {
const exec = 'windowsExec' in settings && settings.windowsExec ? settings.windowsExec : WindowsExternalTerminalService.getDefaultTerminalWindows();
const wt = await WindowsExternalTerminalService.getWtExePath();
return new Promise<number | undefined>((resolve, reject) => {
const title = `"${dir} - ${TERMINAL_TITLE}"`;
const command = `"${args.join('" "')}" & pause`; // use '|' to only pause on non-zero exit code
// merge environment variables into a copy of the process.env
const env = Object.assign({}, getSanitizedEnvironment(process), envVars);
// delete environment variables that have a null value
Object.keys(env).filter(v => env[v] === null).forEach(key => delete env[key]);
const options: any = {
cwd: dir,
env: env,
windowsVerbatimArguments: true
};
let spawnExec: string;
let cmdArgs: string[];
if (path.basename(exec, '.exe') === 'wt') {
// Handle Windows Terminal specially; -d to set the cwd and run a cmd.exe instance
// inside it
spawnExec = exec;
cmdArgs = ['-d', '.', WindowsExternalTerminalService.CMD, '/c', command];
} else if (wt) {
// prefer to use the window terminal to spawn if it's available instead
// of start, since that allows ctrl+c handling (#81322)
spawnExec = wt;
cmdArgs = ['-d', '.', exec, '/c', command];
} else {
spawnExec = WindowsExternalTerminalService.CMD;
cmdArgs = ['/c', 'start', title, '/wait', exec, '/c', `"${command}"`];
}
const cmd = cp.spawn(spawnExec, cmdArgs, options);
cmd.on('error', err => {
reject(improveError(err));
});
resolve(undefined);
});
}
Note the if (path.basename(exec, '.exe') === 'wt') line: exec comes from the setting Terminal > External: Windows Exec. Hence my Option 1 solution: explicitly setting this to wt means that:
const cmd = cp.spawn(spawnExec, cmdArgs, options);
evaluates to:
const cmd = cp.spawn("wt", ...);
So, if Windows Exec is set to anything else (including the default of cmd.exe), it instead evaluates to:
const cmd = cp.spawn(WindowsExternalTerminalService.getWtExePath(), ...);
Either spawn isn't escaping spaces in paths or getWtExePath is returning malformed.