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
60 changes: 39 additions & 21 deletions src/System.Management.Automation/engine/NativeCommandProcessor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,8 @@ internal NativeCommandProcessor(ApplicationInfo applicationInfo, ExecutionContex

//Create input writer for providing input to the process.
_inputWriter = new ProcessInputWriter(Command);

_isTranscribing = this.Command.Context.EngineHostInterface.UI.IsTranscribing;
}

/// <summary>
Expand Down Expand Up @@ -373,8 +375,8 @@ internal override void ProcessRecord()
/// </summary>
private BlockingCollection<ProcessOutputObject> _nativeProcessOutputQueue;

private bool _scrapeHostOutput;

private static bool? s_supportScreenScrape = null;
private bool _isTranscribing;
private Host.Coordinates _startPosition;

/// <summary>
Expand All @@ -398,11 +400,13 @@ private void InitNativeProcess()
// redirecting anything. This is a bit tricky as we always run redirected so
// we have to see if the redirection is actually being done at the topmost level or not.

//Calculate if input and output are redirected.
// Calculate if input and output are redirected.
bool redirectOutput;
bool redirectError;
bool redirectInput;

_startPosition = new Host.Coordinates();

CalculateIORedirection(out redirectOutput, out redirectError, out redirectInput);

// Find out if it's the only command in the pipeline.
Expand All @@ -416,9 +420,6 @@ private void InitNativeProcess()
throw new PipelineStoppedException();
}

_startPosition = new Host.Coordinates();
_scrapeHostOutput = false;

Exception exceptionToRethrow = null;
try
{
Expand All @@ -432,19 +433,10 @@ private void InitNativeProcess()

// Also, store the Raw UI coordinates so that we can scrape the screen after
// if we are transcribing.
try
if (_isTranscribing && (true == s_supportScreenScrape))
{
if (this.Command.Context.EngineHostInterface.UI.IsTranscribing)
{
_scrapeHostOutput = true;
_startPosition = this.Command.Context.EngineHostInterface.UI.RawUI.CursorPosition;
_startPosition.X = 0;
}
}
catch (Host.HostException)
{
// The host doesn't support scraping via its RawUI interface
_scrapeHostOutput = false;
_startPosition = this.Command.Context.EngineHostInterface.UI.RawUI.CursorPosition;
_startPosition.X = 0;
}
}

Expand Down Expand Up @@ -697,9 +689,8 @@ internal override void Complete()
ConsumeAvailableNativeProcessOutput(blocking: true);
_nativeProcess.WaitForExit();

// Capture screen output if we are transcribing
if (this.Command.Context.EngineHostInterface.UI.IsTranscribing &&
_scrapeHostOutput)
// Capture screen output if we are transcribing and running stand alone
if (_isTranscribing && (true == s_supportScreenScrape) && _runStandAlone)
{
Host.Coordinates endPosition = this.Command.Context.EngineHostInterface.UI.RawUI.CursorPosition;
endPosition.X = this.Command.Context.EngineHostInterface.UI.RawUI.BufferSize.Width - 1;
Expand Down Expand Up @@ -1287,6 +1278,33 @@ private void CalculateIORedirection(out bool redirectOutput, out bool redirectEr
}

_runStandAlone = !redirectInput && !redirectOutput && !redirectError;

if (_runStandAlone)
{
if (null == s_supportScreenScrape)
{
try
{
_startPosition = this.Command.Context.EngineHostInterface.UI.RawUI.CursorPosition;
Host.BufferCell[,] bufferContents = this.Command.Context.EngineHostInterface.UI.RawUI.GetBufferContents(
new Host.Rectangle(_startPosition, _startPosition));
s_supportScreenScrape = true;
}
catch (Exception)
{
s_supportScreenScrape = false;
}
}

// if screen scraping isn't supported, we enable redirection so that the output is still transcribed
// as redirected output is always transcribed
if (_isTranscribing && (false == s_supportScreenScrape))
{
redirectOutput = true;
redirectError = true;
_runStandAlone = false;
}
}
}

private bool ValidateExtension(string path)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,20 +107,19 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" {
ValidateTranscription -scriptToExecute $script -outputFilePath $null -expectedError $expectedError
}
It "Transcription should remain active if other runspace in the host get closed" {
try{
try {
$ps = [powershell]::Create()
$ps.addscript("Start-Transcript -path $transcriptFilePath").Invoke()
$ps.addscript('$rs = [system.management.automation.runspaces.runspacefactory]::CreateRunspace()').Invoke()
$ps.addscript('$rs.open()').Invoke()
$ps.addscript('$rs.Dispose()').Invoke()
$ps.addscript('Write-Host "After Dispose"').Invoke()
$ps.addscript("Stop-Transcript").Invoke()
} finally {
if ($null -ne $ps) {
$ps.Dispose()
}
} finally {
if ($null -ne $ps) {
$ps.Dispose()
}

}

Test-Path $transcriptFilePath | Should be $true
$transcriptFilePath | Should contain "After Dispose"
Expand All @@ -136,4 +135,15 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" {
$transcriptFilePath | Should contain "PowerShell transcript end"
}

}
It "Transcription should record native command output" {
$script = {
Start-Transcript -Path $transcriptFilePath
hostname
Stop-Transcript }
& $script
Test-Path $transcriptFilePath | Should be $true

$machineName = [System.Environment]::MachineName
$transcriptFilePath | Should contain $machineName
}
}
15 changes: 15 additions & 0 deletions test/powershell/engine/Job/Jobs.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,21 @@ Describe 'Basic Job Tests' -Tags 'CI' {
Receive-Job $job -wait | should be 1
}

It "Create job with native command" {
try {
$nativeJob = Start-job { powershell -c 1+1 }
$nativeJob | Wait-Job
$nativeJob.State | Should BeExactly "Completed"
$nativeJob.HasMoreData | Should Be $true
Receive-Job $nativeJob | Should BeExactly 2
Remove-Job $nativeJob
{ Get-Job $nativeJob -ErrorAction Stop } | ShouldBeErrorId "JobWithSpecifiedNameNotFound,Microsoft.PowerShell.Commands.GetJobCommand"
}
finally {
Remove-Job $nativeJob -Force -ErrorAction SilentlyContinue
}
}

AfterAll {
Remove-Job $job -Force
}
Expand Down