Use PowerShell call operator when shell integration is unavailable#14585
Use PowerShell call operator when shell integration is unavailable#14585owevertonguedes wants to merge 1 commit into
Conversation
"Run C/C++ File" builds the command with buildShellCommandLine and sends it via sendText when the terminal has no shell integration. That path quotes a program path containing spaces but never prepends the call operator, so PowerShell evaluates the quoted path as a string literal and echoes it instead of running the program. The shell-integration path already handles this, so extract its PowerShell detection into isPowerShellTerminal() and reuse it in the sendText path. Closes microsoft#14583
|
@microsoft-github-policy-service agree |
|
@owevertonguedes, so are there versions of PowerShell that do not support shell integration, or is there some VS Code bug where it fails to activate? The code changes look reasonable, but I'd like to understand the case where shell integration doesn't work with PowerShell. |
There was a problem hiding this comment.
Pull request overview
This PR fixes “Run C/C++ File” on PowerShell terminals when shell integration is unavailable by ensuring the command is invoked with the PowerShell call operator so spaced executable paths are executed rather than echoed.
Changes:
- Extracts PowerShell terminal detection into a reusable
isPowerShellTerminal()helper. - Reuses that helper in the no-shell-integration fallback to prefix commands with
&for PowerShell.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| const cmdLine: string = buildShellCommandLine('', program, args, true); | ||
| this.terminal.sendText(cmdLine); | ||
| // buildShellCommandLine quotes the path, and PowerShell evaluates a quoted path as a string | ||
| // literal instead of running it, so the call operator is required to invoke it. | ||
| this.terminal.sendText(this.isPowerShellTerminal() ? `& ${cmdLine}` : cmdLine); |
|
Thanks for the review. Honest answer: I can't tell you for certain why shell integration wasn't available in the reporter's case — the issue doesn't include that diagnostic, and I wasn't able to reproduce it myself (I don't have a Windows/PowerShell environment). What the code does tell us: the reported output (a quoted path echoed back, no What I can't tell you is which of the two cases you're describing this was:
The reporter's shell-integration diagnostics would most likely separate these two, but I don't want to over-scope the PR. What this change does in either case: the |
Closes #14583
Problem
When "Run C/C++ File" targets a terminal without shell integration,
launchIntegratedTerminalfalls back tobuildShellCommandLine(...)+terminal.sendText(...). That fallback quotes a program path containing spaces but never prepends the PowerShell call operator, so PowerShell evaluates the quoted path as a string literal and echoes it back instead of executing the program:This matches the reported output exactly: had the shell-integration path run, the command would have been rendered as
& "C:\...\main.exe".The shell-integration path already handles PowerShell correctly (added in #14351), but its detection logic was inline and therefore unavailable to the fallback.
buildShellCommandLinealso carries an explicit// TODO: Support launching with PowerShell.Change
isPowerShellTerminal()helper (behavior unchanged, including the "assume PowerShell on Windows when the shell is unknown" fallback).sendTextpath to prepend&for PowerShell.No behavior change for cmd.exe or POSIX shells, or for terminals that do have shell integration.
Testing
tsc --noEmitpasses for the changed file, andeslintis clean.runWithoutDebugging.terminals.test.tsmatrix already covers a spaced executable across theundefined/Command Prompt/PowerShellprofiles, but it only exercises the shell-integration path, which is why this fallback regressed unnoticed.I could not exercise the Windows/PowerShell fallback end-to-end (no Windows machine available), so I would appreciate a careful look at that path in review.