diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs
index 45fb2f591..af7856325 100644
--- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs
+++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs
@@ -185,6 +185,8 @@ namespace System.Management.Automation
//Create input writer for providing input to the process.
_inputWriter = new ProcessInputWriter(Command);
+
+ _isTranscribing = this.Command.Context.EngineHostInterface.UI.IsTranscribing;
}
///
@@ -373,8 +375,8 @@ namespace System.Management.Automation
///
private BlockingCollection _nativeProcessOutputQueue;
- private bool _scrapeHostOutput;
-
+ private static bool? s_supportScreenScrape = null;
+ private bool _isTranscribing;
private Host.Coordinates _startPosition;
///
@@ -398,11 +400,13 @@ namespace System.Management.Automation
// 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.
@@ -416,9 +420,6 @@ namespace System.Management.Automation
throw new PipelineStoppedException();
}
- _startPosition = new Host.Coordinates();
- _scrapeHostOutput = false;
-
Exception exceptionToRethrow = null;
try
{
@@ -432,19 +433,10 @@ namespace System.Management.Automation
// 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;
}
}
@@ -697,9 +689,8 @@ namespace System.Management.Automation
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;
@@ -1287,6 +1278,33 @@ namespace System.Management.Automation
}
_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)
diff --git a/test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1 b/test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1
index cd5907f87..2d3c28aba 100644
--- a/test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1
+++ b/test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1
@@ -107,7 +107,7 @@ 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()
@@ -115,12 +115,11 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" {
$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"
@@ -136,4 +135,15 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" {
$transcriptFilePath | Should contain "PowerShell transcript end"
}
-}
\ No newline at end of file
+ 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
+ }
+}
diff --git a/test/powershell/engine/Job/Jobs.Tests.ps1 b/test/powershell/engine/Job/Jobs.Tests.ps1
index 789160d6b..dd28559df 100644
--- a/test/powershell/engine/Job/Jobs.Tests.ps1
+++ b/test/powershell/engine/Job/Jobs.Tests.ps1
@@ -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
}