commit
cfba7537f3
|
@ -720,7 +720,7 @@ namespace System.Management.Automation.Runspaces
|
|||
CustomControl.Create(outOfBand: true)
|
||||
.StartEntry()
|
||||
.AddScriptBlockExpressionBinding(@"
|
||||
if ($_.FullyQualifiedErrorId -ne ""NativeCommandErrorMessage"" -and $ErrorView -ne ""CategoryView"")
|
||||
if (($_.FullyQualifiedErrorId -ne ""NativeCommandErrorMessage"" -and $_.FullyQualifiedErrorId -ne ""NativeCommandError"") -and $ErrorView -ne ""CategoryView"")
|
||||
{
|
||||
$myinv = $_.InvocationInfo
|
||||
if ($myinv -and $myinv.MyCommand)
|
||||
|
@ -767,7 +767,7 @@ namespace System.Management.Automation.Runspaces
|
|||
}
|
||||
")
|
||||
.AddScriptBlockExpressionBinding(@"
|
||||
if ($_.FullyQualifiedErrorId -eq ""NativeCommandErrorMessage"") {
|
||||
if ($_.FullyQualifiedErrorId -eq ""NativeCommandErrorMessage"" -or $_.FullyQualifiedErrorId -eq ""NativeCommandError"") {
|
||||
$_.Exception.Message
|
||||
}
|
||||
else
|
||||
|
|
|
@ -2841,7 +2841,7 @@ namespace System.Management.Automation
|
|||
/// but the command failure will ultimately be
|
||||
/// <see cref="System.Management.Automation.ActionPreferenceStopException"/>,
|
||||
/// </remarks>
|
||||
internal void _WriteErrorSkipAllowCheck(ErrorRecord errorRecord, ActionPreference? actionPreference = null)
|
||||
internal void _WriteErrorSkipAllowCheck(ErrorRecord errorRecord, ActionPreference? actionPreference = null, bool isNativeError = false)
|
||||
{
|
||||
ThrowIfStopping();
|
||||
|
||||
|
@ -2923,7 +2923,9 @@ namespace System.Management.Automation
|
|||
PSObject errorWrap = PSObject.AsPSObject(errorRecord);
|
||||
// It's possible we've already added the member (this method is recursive sometimes
|
||||
// when tracing), so don't add the member again.
|
||||
if (errorWrap.Members["writeErrorStream"] == null)
|
||||
|
||||
// We don't add a note property on messages that comes from stderr stream.
|
||||
if (!isNativeError && errorWrap.Members["writeErrorStream"] == null)
|
||||
{
|
||||
PSNoteProperty note = new PSNoteProperty("writeErrorStream", true);
|
||||
errorWrap.Properties.Add(note);
|
||||
|
|
|
@ -947,7 +947,7 @@ namespace System.Management.Automation
|
|||
ErrorRecord record = outputValue.Data as ErrorRecord;
|
||||
Dbg.Assert(record != null, "ProcessReader should ensure that data is ErrorRecord");
|
||||
record.SetInvocationInfo(this.Command.MyInvocation);
|
||||
this.commandRuntime._WriteErrorSkipAllowCheck(record);
|
||||
this.commandRuntime._WriteErrorSkipAllowCheck(record, isNativeError: true);
|
||||
}
|
||||
else if (outputValue.Stream == MinishellStream.Output)
|
||||
{
|
||||
|
@ -1880,17 +1880,11 @@ namespace System.Management.Automation
|
|||
//
|
||||
// Wrap the rest of the output in ErrorRecords with the "NativeCommandErrorMessage" error ID
|
||||
//
|
||||
char[] buffer = new char[4096];
|
||||
|
||||
int read = 0;
|
||||
|
||||
while ((read = _streamReader.Read(buffer, 0, buffer.Length)) != 0)
|
||||
while ((line = _streamReader.ReadLine()) != null)
|
||||
{
|
||||
StringBuilder errorMessage = new StringBuilder().Append(buffer, 0, read);
|
||||
|
||||
AddObjectToWriter(
|
||||
new ErrorRecord(
|
||||
new RemoteException(errorMessage.ToString()),
|
||||
new RemoteException(line),
|
||||
"NativeCommandErrorMessage",
|
||||
ErrorCategory.NotSpecified,
|
||||
null),
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
Describe "Native streams behavior with PowerShell" -Tags 'CI' {
|
||||
$powershell = Join-Path -Path $PsHome -ChildPath "powershell"
|
||||
|
||||
Context "Error stream" {
|
||||
# we are using powershell itself as an example of a native program.
|
||||
# we can create a behavior we want on the fly and test complex scenarios.
|
||||
|
||||
$error.Clear()
|
||||
|
||||
$command = [string]::Join('', @(
|
||||
'[Console]::Error.Write(\"foo`n`nbar`n`nbaz\"); ',
|
||||
'[Console]::Error.Write(\"middle\"); ',
|
||||
'[Console]::Error.Write(\"foo`n`nbar`n`nbaz\")'
|
||||
))
|
||||
|
||||
$out = & $powershell -noprofile -command $command 2>&1
|
||||
|
||||
# this check should be the first one, because $error is a global shared variable
|
||||
It 'should not add records to $error variable' {
|
||||
# we are keeping existing Windows PS v5.1 behavior for $error variable
|
||||
$error.Count | Should Be 9
|
||||
}
|
||||
|
||||
It 'uses ErrorRecord object to return stderr output' {
|
||||
($out | measure).Count | Should BeGreaterThan 1
|
||||
|
||||
$out[0] | Should BeOfType 'System.Management.Automation.ErrorRecord'
|
||||
$out[0].FullyQualifiedErrorId | Should Be 'NativeCommandError'
|
||||
|
||||
$out | Select-Object -Skip 1 | % {
|
||||
$_ | Should BeOfType 'System.Management.Automation.ErrorRecord'
|
||||
$_.FullyQualifiedErrorId | Should Be 'NativeCommandErrorMessage'
|
||||
}
|
||||
}
|
||||
|
||||
It 'uses correct exception messages for error stream' {
|
||||
($out | measure).Count | Should Be 9
|
||||
$out[0].Exception.Message | Should Be 'foo'
|
||||
$out[1].Exception.Message | Should Be ''
|
||||
$out[2].Exception.Message | Should Be 'bar'
|
||||
$out[3].Exception.Message | Should Be ''
|
||||
$out[4].Exception.Message | Should Be 'bazmiddlefoo'
|
||||
$out[5].Exception.Message | Should Be ''
|
||||
$out[6].Exception.Message | Should Be 'bar'
|
||||
$out[7].Exception.Message | Should Be ''
|
||||
$out[8].Exception.Message | Should Be 'baz'
|
||||
}
|
||||
|
||||
It 'preserves error stream as is with Out-String' {
|
||||
($out | Out-String).Replace("`r", '') | Should Be "foo`n`nbar`n`nbazmiddlefoo`n`nbar`n`nbaz`n"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue