Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 32 additions & 29 deletions src/System.Management.Automation/engine/NativeCommandProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -815,12 +815,6 @@ private ProcessOutputObject DequeueProcessOutput(bool blocking)
{
if (blocking)
{
if (_stdOutByteTransfer is not null)
{
_stdOutByteTransfer.EOF.GetAwaiter().GetResult();
return null;
}

// If adding was completed and collection is empty (IsCompleted == true)
// there is no need to do a blocking Take(), we should just return.
if (!_nativeProcessOutputQueue.IsCompleted)
Expand All @@ -842,39 +836,48 @@ private ProcessOutputObject DequeueProcessOutput(bool blocking)

return null;
}
else
{
if (_stdOutByteTransfer is not null)
{
return null;
}

ProcessOutputObject record = null;
_nativeProcessOutputQueue.TryTake(out record);
return record;
}
_nativeProcessOutputQueue.TryTake(out ProcessOutputObject record);
return record;
}

/// <summary>
/// Read the output from the native process and send it down the line.
/// </summary>
private void ConsumeAvailableNativeProcessOutput(bool blocking)
{
if (!_isRunningInBackground)
if (_isRunningInBackground)
{
if (_nativeProcess.StartInfo.RedirectStandardOutput || _nativeProcess.StartInfo.RedirectStandardError)
return;
}

bool stdOutRedirected = _nativeProcess.StartInfo.RedirectStandardOutput;
bool stdErrRedirected = _nativeProcess.StartInfo.RedirectStandardError;
if (stdOutRedirected && _stdOutByteTransfer is not null)
{
if (blocking)
{
ProcessOutputObject record;
while ((record = DequeueProcessOutput(blocking)) != null)
{
if (this.Command.Context.CurrentPipelineStopping)
{
this.StopProcessing();
return;
}
_stdOutByteTransfer.EOF.GetAwaiter().GetResult();
}

if (!stdErrRedirected)
{
return;
}
}

ProcessOutputRecord(record);
if (stdOutRedirected || stdErrRedirected)
{
ProcessOutputObject record;
while ((record = DequeueProcessOutput(blocking)) != null)
{
if (this.Command.Context.CurrentPipelineStopping)
{
this.StopProcessing();
return;
}

ProcessOutputRecord(record);
}
}
}
Expand All @@ -887,7 +890,7 @@ internal override void Complete()
if (!_isRunningInBackground)
{
// Wait for input writer to finish.
if (!UpstreamIsNativeCommand)
if (!UpstreamIsNativeCommand || _nativeProcess.StartInfo.RedirectStandardError)
{
_inputWriter.Done();
}
Expand Down Expand Up @@ -1772,7 +1775,7 @@ public ProcessOutputHandler(

// we incrementing refCount on the same thread and before running any processing
// so it's safe to do it without Interlocked.
if (process.StartInfo.RedirectStandardOutput)
if (process.StartInfo.RedirectStandardOutput && stdOutDestination is null)
{
_refCount++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,12 @@ Describe "Native Command Processor" -tags "Feature" {
Wait-UntilTrue -sb { (Get-Process mmc).Count -gt 0 } -TimeoutInMilliseconds 5000 -IntervalInMilliseconds 1000 | Should -BeTrue
Get-Process mmc | Stop-Process
}

It 'Can redirect stdout and stderr to different files' {
testexe -stderrandout testing > $TestDrive/stdout.txt 2> $TestDrive/stderr.txt
Get-Content $TestDrive/stdout.txt | Should -Be testing
Get-Content $TestDrive/stderr.txt | Should -Be gnitset
}
}

Describe "Open a text file with NativeCommandProcessor" -tags @("Feature", "RequireAdminOnWindows") {
Expand Down
5 changes: 5 additions & 0 deletions test/tools/TestExe/TestExe.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using System.Runtime.InteropServices;
using System.IO;
using System.Globalization;
using System.Linq;

namespace TestExe
{
Expand Down Expand Up @@ -36,6 +37,10 @@ private static int Main(string[] args)
case "-stderr":
Console.Error.WriteLine(args[1]);
break;
case "-stderrandout":
Console.WriteLine(args[1]);
Console.Error.WriteLine(new string(args[1].ToCharArray().Reverse().ToArray()));
break;
case "-readbytes":
ReadBytes();
break;
Expand Down