Repository navigation
Captured native command that fails to start reports 'StandardOutputEncoding is only supported when standard output is redirected' instead of the real launch error #28225
Description
Prerequisites
- Write a descriptive title.
- Make sure you are able to repro it on the latest released version (reproduced on 7.6.6; the code path is unchanged in the v7.6.7 tag, lines cited below)
- Search the existing issues.
- Refer to the FAQ.
- Refer to Differences between Windows PowerShell 5.1 and PowerShell.
Steps to reproduce
A native command that cannot be started (here a file that is not a valid PE image) reports a different error depending on whether its output is captured or piped:
Set-Content -Path "$env:TEMP\notpe.exe" -Value 'plain text, not a PE image'
$x = & "$env:TEMP\notpe.exe" # output captured
& "$env:TEMP\notpe.exe" | Out-Null # output piped, for comparisonWe first hit this with an intermittent failure launching a Windows App Execution Alias (python3.exe under %LOCALAPPDATA%\Microsoft\WindowsApps) from a captured call. The real Win32 error could not be recovered from the message PowerShell produced.
Expected behavior
PS> $x = & "$env:TEMP\notpe.exe"
ResourceUnavailable: Program 'notpe.exe' failed to run: An error occurred trying to start process 'C:\...\notpe.exe' with working directory 'C:\...'. The specified executable is not a valid application for this OS platform.Both forms should report the start failure the way the piped form does.
Actual behavior
PS> $x = & "$env:TEMP\notpe.exe"
ResourceUnavailable: Program 'notpe.exe' failed to run: StandardOutputEncoding is only supported when standard output is redirected.
PS> & "$env:TEMP\notpe.exe" | Out-Null
ResourceUnavailable: Program 'notpe.exe' failed to run: An error occurred trying to start process 'C:\...\notpe.exe' with working directory 'C:\...'. The specified executable is not a valid application for this OS platform.The captured form loses the original Win32 error, which makes real launch failures hard to diagnose.
Error details
PS> Get-Error
Exception :
Type : System.Management.Automation.ApplicationFailedException
TargetSite :
Name : InitNativeProcess
DeclaringType : [System.Management.Automation.NativeCommandProcessor]
MemberType : Method
Module : System.Management.Automation.dll
Message : Program 'notpe.exe' failed to run: StandardOutputEncoding is only supported when standard output is redirected.
InnerException :
Type : System.InvalidOperationException
TargetSite :
Name : Start
DeclaringType : [System.Diagnostics.Process]
MemberType : Method
Module : System.Diagnostics.Process.dll
Message : StandardOutputEncoding is only supported when standard output is redirected.
Source : System.Diagnostics.Process
HResult : -2146233079
StackTrace :
at System.Diagnostics.Process.Start()
at System.Management.Automation.NativeCommandProcessor.InitNativeProcess()
Source : System.Management.Automation
HResult : -2146233087
StackTrace :
at System.Management.Automation.NativeCommandProcessor.InitNativeProcess()
at System.Management.Automation.NativeCommandProcessor.Prepare(IDictionary psDefaultParameterValues)
at System.Management.Automation.CommandProcessorBase.DoPrepare(IDictionary psDefaultParameterValues)
at System.Management.Automation.Internal.PipelineProcessor.Start(Boolean incomingStream)
at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(Object input)
CategoryInfo : ResourceUnavailable: (:) [], ParentContainsErrorRecordException
FullyQualifiedErrorId : NativeCommandFailed(Trimmed to the relevant members; the omitted ErrorRecord and InvocationInfo blocks only repeat the script position.)
Environment data
Name Value
---- -----
PSVersion 7.6.6
PSEdition Core
GitCommitId 7.6.6
OS Microsoft Windows 10.0.26200
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
PSRemotingProtocolVersion 2.4
SerializationVersion 1.1.0.1
WSManStackVersion 3.0Visuals
None.
Cause and suggested fix
In src/System.Management.Automation/engine/NativeCommandProcessor.cs (v7.6.7 tag), GetProcessStartInfo sets StandardOutputEncoding and StandardErrorEncoding whenever output or error is redirected (lines 1651 and 1657). When the first Process.Start() throws Win32Exception for a solo command, the ShellExecute fallback (lines 869 to 873) sets UseShellExecute = true and clears the three RedirectStandard* flags, but leaves both encodings set. .NET's Process.Start then throws InvalidOperationException ("StandardOutputEncoding is only supported when standard output is redirected"), and that exception replaces the original Win32 error. The piped form never takes the fallback (soloCommand is false there), so it reports the real error. The same code is on master at fbb4fd5.
Suggested fix: clear StandardOutputEncoding and StandardErrorEncoding (set them to null) together with the redirect flags before the ShellExecute retry, and when that retry fails as well, surface the original Win32Exception as the inner exception so the real launch error is not lost.
Activity