Repository navigation
fix(hook): show why a captured program failed to start in PowerShell - #62
Merged
Merged
Conversation
When a native program cannot be started while its output is piped, pwsh retries through ShellExecute without the pipe but leaves StandardOutputEncoding set, so the retry fails with "StandardOutputEncoding is only supported when standard output is redirected" and the real reason is lost (PowerShell/PowerShell#28225). Every captured line pipes its output, so under the hook any start failure surfaced this way, and the ShellExecute fallback a plain shell gets never ran. When the failing line is that one program alone, with plain-value arguments, nothing in it ran, so the hook now runs it again without the pipe: it starts as it would without the hook, or fails with the real reason. Lines that did more than start the program keep the old behavior. Tests: a file that is not a program reports the same error with and without the hook; powershell.exe, pwsh and an iex-piped installer script (in this shell and in a child one) start and are captured.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Under the PowerShell hook, a program that fails to start reports
instead of the reason. Seen launching
powershell -ExecutionPolicy Bypass -c "irm ... | iex"in a pwsh 7.6 session over ssh.Cause
pwsh engine bug PowerShell/PowerShell#28225 (open). In
NativeCommandProcessor.InitNativeProcess, aWin32ExceptionfromProcess.Starton Windows desktops falls back toShellExecutefor a solo command: it clearsRedirectStandardOutputbut leaves theStandardOutputEncodingset byGetProcessStartInfowhen output is redirected, soProcess.StartthrowsInvalidOperationException. The hook runs every captured line as. $block *>&1 | __cdgRecord, so every native command in it has its output redirected and any start failure goes down this path. Without the hook the same command is not redirected, gets theShellExecutefallback, and reports the real error when that fails too. This has been the case since the capture pipe was added; the$^/$$change is unrelated.Repro without the hook:
Set-Content notpe.exe x; $x = & .\notpe.exe.Fix
When a captured line fails this way (
ApplicationFailedExceptionwrapping anInvalidOperationExceptionfromProcess.Start, pointing at the line itself) and the line is that one program alone with plain-value arguments, nothing in it ran, so__cdgruns it again without the pipe. It starts as it would without the hook, or fails with the real reason. That line is not captured. Lines that did more (a; b.exe,b.exe $(...), a function that calls the program) keep the old behavior, since running them again would repeat work.Tests
test_pwsh_program_that_cannot_start_says_why: a non-PE.exereports the real reason with and without the hook (fails on main); a line that did more is not run again.test_pwsh_captured_line_starts_windows_powershell_and_pwsh:powershell.exe -c,pwsh -c, and an installer-shaped multi-line script (& { ... },$ErrorActionPreference = 'Stop', a native call) piped toiexin this shell, inpowershell -cand inpwsh -call run and are captured.Full suite: 311 passed, 5 skipped, 1 xfailed locally (Windows, pwsh 7.6.9); ruff check and format clean.