From 9ac701dbee5d7b9bb0d7875552e661f94b2c22e1 Mon Sep 17 00:00:00 2001 From: Hubert Bukowski Date: Sat, 16 Jun 2018 18:11:21 +0200 Subject: [PATCH] Fix conditions for transcription of Write-Information command. (#6917) Makes a transcription of Write-Information command consistent with $InfomrationPreference variable. --- .../commands/utility/WriteConsoleCmdlet.cs | 1 - ...ConsoleHostUserInterfacePromptForChoice.cs | 18 ++- .../engine/MshCommandRuntime.cs | 16 +- .../engine/Utils.cs | 1 + .../InternalHostUserInterfaceStrings.resx | 3 - .../Start-Transcript.Tests.ps1 | 151 ++++++++++++++++-- 6 files changed, 163 insertions(+), 27 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs index 2c0ce8f21d..bf51fd2354 100644 --- a/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs +++ b/src/Microsoft.PowerShell.Commands.Utility/commands/utility/WriteConsoleCmdlet.cs @@ -137,7 +137,6 @@ namespace Microsoft.PowerShell.Commands } this.WriteInformation(informationMessage, new string[] { "PSHOST" }); - this.Host.UI.TranscribeResult(result); } private Boolean _notAppendNewline = false; diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs index ac50c61f7c..06dbde6c01 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostUserInterfacePromptForChoice.cs @@ -107,7 +107,7 @@ namespace Microsoft.PowerShell WriteChoicePrompt(hotkeysAndPlainLabels, defaultChoiceKeys, false); ReadLineResult rlResult; - string response = ReadLine(false, string.Empty, out rlResult, true, true); + string response = ReadChoiceResponse(out rlResult); if (rlResult == ReadLineResult.endedOnBreak) { @@ -253,7 +253,7 @@ namespace Microsoft.PowerShell WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(choiceMsg)); ReadLineResult rlResult; - string response = ReadLine(false, string.Empty, out rlResult, true, true); + string response = ReadChoiceResponse(out rlResult); if (rlResult == ReadLineResult.endedOnBreak) { @@ -412,6 +412,19 @@ namespace Microsoft.PowerShell WriteToConsole(fg, bg, trimEnd ? text.TrimEnd(null) : text); } + private string ReadChoiceResponse(out ReadLineResult result) + { + result = ReadLineResult.endedOnEnter; + return InternalTestHooks.ForcePromptForChoiceDefaultOption + ? string.Empty + : ReadLine( + endOnTab: false, + initialContent: string.Empty, + result: out result, + calledFromPipeline: true, + transcribeResult: true); + } + private void ShowChoiceHelp(Collection choices, string[,] hotkeysAndPlainLabels) { Dbg.Assert(choices != null, "choices: expected a value"); @@ -473,4 +486,3 @@ namespace Microsoft.PowerShell } } } // namespace - diff --git a/src/System.Management.Automation/engine/MshCommandRuntime.cs b/src/System.Management.Automation/engine/MshCommandRuntime.cs index 54a98fc0ce..8722b6d604 100644 --- a/src/System.Management.Automation/engine/MshCommandRuntime.cs +++ b/src/System.Management.Automation/engine/MshCommandRuntime.cs @@ -748,8 +748,7 @@ namespace System.Management.Automation // if (null == Host || null == Host.UI) { - Diagnostics.Assert(false, "No host in CommandBase.WriteVerbose()"); - throw PSTraceSource.NewInvalidOperationException(); + throw PSTraceSource.NewInvalidOperationException("No host in CommandBase.WriteInformation()"); } CBhost.InternalUI.WriteInformationRecord(record); @@ -821,11 +820,14 @@ namespace System.Management.Automation CBhost.InternalUI.WriteLine(record.ToString()); } } - else - { - // Only transcribe informational messages here. Transcription of PSHost-targeted messages is done in the InternalUI.Write* methods. - CBhost.InternalUI.TranscribeResult(StringUtil.Format(InternalHostUserInterfaceStrings.InformationFormatString, record.ToString())); - } + } + + // Both informational and PSHost-targeted messages are transcribed here. + // The only difference between these two is that PSHost-targeted messages are transcribed + // even if InformationAction is SilentlyContinue. + if (record.Tags.Contains("PSHOST") || (preference != ActionPreference.SilentlyContinue)) + { + CBhost.InternalUI.TranscribeResult(record.ToString()); } } diff --git a/src/System.Management.Automation/engine/Utils.cs b/src/System.Management.Automation/engine/Utils.cs index 1e07e4b70a..f1a4bdc6c7 100644 --- a/src/System.Management.Automation/engine/Utils.cs +++ b/src/System.Management.Automation/engine/Utils.cs @@ -1434,6 +1434,7 @@ namespace System.Management.Automation.Internal internal static bool UseDebugAmsiImplementation; internal static bool BypassAppLockerPolicyCaching; internal static bool BypassOnlineHelpRetrieval; + internal static bool ForcePromptForChoiceDefaultOption; // Stop/Restart/Rename Computer tests internal static bool TestStopComputer; diff --git a/src/System.Management.Automation/resources/InternalHostUserInterfaceStrings.resx b/src/System.Management.Automation/resources/InternalHostUserInterfaceStrings.resx index b55e117bac..a40b58cebc 100644 --- a/src/System.Management.Automation/resources/InternalHostUserInterfaceStrings.resx +++ b/src/System.Management.Automation/resources/InternalHostUserInterfaceStrings.resx @@ -186,9 +186,6 @@ DEBUG: {0} - - INFO: {0} - The host is not currently transcribing. 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 5b4b3ab233..423c4176ea 100644 --- a/test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.Powershell.Host/Start-Transcript.Tests.ps1 @@ -16,7 +16,7 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" { #Add sample text to the file $content = "This is sample text!" $content | Out-File -FilePath $outputFilePath - Test-Path $outputFilePath | Should be $true + Test-Path $outputFilePath | Should -BeTrue } try { @@ -27,16 +27,16 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" { if($expectedError) { $ps.hadErrors | Should -BeTrue - $ps.Streams.Error.FullyQualifiedErrorId | Should be $expectedError + $ps.Streams.Error.FullyQualifiedErrorId | Should -Be $expectedError } else { $ps.addscript("Get-Date").Invoke() $ps.commands.clear() $ps.addscript("Stop-Transcript").Invoke() Test-Path $outputFilePath | Should -BeTrue - $outputFilePath | should FileContentMatch "Get-Date" + $outputFilePath | Should -FileContentMatch "Get-Date" if($append) { - $outputFilePath | Should FileContentMatch $content + $outputFilePath | Should -FileContentMatch $content } } } finally { @@ -53,6 +53,7 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" { AfterEach { Remove-Item $transcriptFilePath -ErrorAction SilentlyContinue + [System.Management.Automation.Internal.InternalTestHooks]::SetTestHook('ForcePromptForChoiceDefaultOption', $False) } It "Should create Transcript file at default path" { @@ -122,8 +123,8 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" { } } - Test-Path $transcriptFilePath | Should be $true - $transcriptFilePath | Should FileContentMatch "After Dispose" + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -FileContentMatch "After Dispose" } It "Transcription should be closed if the only runspace gets closed" { @@ -131,20 +132,144 @@ Describe "Start-Transcript, Stop-Transcript tests" -tags "CI" { $powerShellCommand = $powerShellPath + ' -c "start-transcript $transcriptFilePath; Write-Host ''Before Dispose'';"' Invoke-Expression $powerShellCommand - Test-Path $transcriptFilePath | Should -BeTrue - $transcriptFilePath | Should FileContentMatch "Before Dispose" - $transcriptFilePath | Should FileContentMatch "PowerShell transcript end" + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -FileContentMatch "Before Dispose" + $transcriptFilePath | Should -FileContentMatch "PowerShell transcript end" } It "Transcription should record native command output" { $script = { Start-Transcript -Path $transcriptFilePath hostname - Stop-Transcript } - & $script - Test-Path $transcriptFilePath | Should -BeTrue + Stop-Transcript + } + & $script + + $transcriptFilePath | Should -Exist $machineName = [System.Environment]::MachineName - $transcriptFilePath | Should FileContentMatch $machineName + $transcriptFilePath | Should -FileContentMatch $machineName + } + + It "Transcription should record Write-Information output when InformationAction is set to Continue" { + [String]$message = New-Guid + $script = { + Start-Transcript -Path $transcriptFilePath + Write-Information -Message $message -InformationAction Continue + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -Not -FileContentMatch "INFO: " + $transcriptFilePath | Should -FileContentMatch $message + } + + It "Transcription should not record Write-Information output when InformationAction is set to SilentlyContinue" { + [String]$message = New-Guid + $script = { + Start-Transcript -Path $transcriptFilePath + Write-Information -Message $message -InformationAction SilentlyContinue + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -Not -FileContentMatch "INFO: " + $transcriptFilePath | Should -Not -FileContentMatch $message + } + + It "Transcription should not record Write-Information output when InformationAction is set to Ignore" { + [String]$message = New-Guid + $script = { + Start-Transcript -Path $transcriptFilePath + Write-Information -Message $message -InformationAction Ignore + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -Not -FileContentMatch "INFO: " + $transcriptFilePath | Should -Not -FileContentMatch $message + } + + It "Transcription should record Write-Information output in correct order when InformationAction is set to Inquire" { + [String]$message = New-Guid + $newLine = [System.Environment]::NewLine + $expectedContent = "$message$($newLine)Confirm$($newLine)Continue with this operation?" + $script = { + [System.Management.Automation.Internal.InternalTestHooks]::SetTestHook('ForcePromptForChoiceDefaultOption', $True) + Start-Transcript -Path $transcriptFilePath + Write-Information -Message $message -InformationAction Inquire + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -Not -FileContentMatch "INFO: " + $transcriptFilePath | Should -FileContentMatchMultiline $expectedContent + } + + It "Transcription should record Write-Host output when InformationAction is set to Continue" { + [String]$message = New-Guid + $script = { + Start-Transcript -Path $transcriptFilePath + Write-Host -Message $message -InformationAction Continue + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -FileContentMatch $message + } + + It "Transcription should record Write-Host output when InformationAction is set to SilentlyContinue" { + [String]$message = New-Guid + $script = { + Start-Transcript -Path $transcriptFilePath + Write-Host -Message $message -InformationAction SilentlyContinue + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -FileContentMatch $message + } + + It "Transcription should not record Write-Host output when InformationAction is set to Ignore" { + [String]$message = New-Guid + $script = { + Start-Transcript -Path $transcriptFilePath + Write-Host -Message $message -InformationAction Ignore + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -Not -FileContentMatch $message + } + + It "Transcription should record Write-Host output in correct order when InformationAction is set to Inquire" { + [String]$message = New-Guid + $newLine = [System.Environment]::NewLine + $expectedContent = "$message$($newLine)Confirm$($newLine)Continue with this operation?" + $script = { + [System.Management.Automation.Internal.InternalTestHooks]::SetTestHook('ForcePromptForChoiceDefaultOption', $True) + Start-Transcript -Path $transcriptFilePath + Write-Host -Message $message -InformationAction Inquire + Stop-Transcript + } + + & $script + + $transcriptFilePath | Should -Exist + $transcriptFilePath | Should -FileContentMatchMultiline $expectedContent } }