From 16cc9aaaf825db79eeba65fd0fdc3f43c0c6a8d8 Mon Sep 17 00:00:00 2001 From: Steve Lee Date: Wed, 7 Oct 2020 00:58:24 -0700 Subject: [PATCH] Fix blocking wait when starting file associated with a Windows application (#13750) * Fix blocking wait when starting file associated with a Windows application in elevated process * refactor check if app is WindowsApp --- .../engine/NativeCommandProcessor.cs | 48 ++++--------------- .../NativeCommandProcessor.Tests.ps1 | 9 ++++ 2 files changed, 18 insertions(+), 39 deletions(-) diff --git a/src/System.Management.Automation/engine/NativeCommandProcessor.cs b/src/System.Management.Automation/engine/NativeCommandProcessor.cs index b9c101edcd..b16f5231d2 100644 --- a/src/System.Management.Automation/engine/NativeCommandProcessor.cs +++ b/src/System.Management.Automation/engine/NativeCommandProcessor.cs @@ -221,29 +221,6 @@ namespace System.Management.Automation } } - /// - /// Gets true if Path is Console Application. - /// - private bool IsConsoleApplication => !IsWindowsApplication; - - /// - /// Gets true if Path is Windows Application. - /// - private bool IsWindowsApplication - { - get - { - if (!_isWindowsApplication.HasValue) - { - _isWindowsApplication = CheckIfWindowsApplication(Path); - } - - return _isWindowsApplication.Value; - } - } - - private bool? _isWindowsApplication; - #endregion ctor/native command properties #region parameter binder @@ -423,7 +400,8 @@ namespace System.Management.Automation _startPosition = new Host.Coordinates(); - CalculateIORedirection(out redirectOutput, out redirectError, out redirectInput); + bool isWindowsApplication = IsWindowsApplication(this.Path); + CalculateIORedirection(isWindowsApplication, out redirectOutput, out redirectError, out redirectInput); // Find out if it's the only command in the pipeline. bool soloCommand = this.Command.MyInvocation.PipelineLength == 1; @@ -498,7 +476,8 @@ namespace System.Management.Automation bool notDone = true; if (!string.IsNullOrEmpty(executable)) { - if (CheckIfConsoleApplication(executable)) + isWindowsApplication = IsWindowsApplication(executable); + if (!isWindowsApplication) { // Allocate a console if there isn't one attached already... ConsoleVisibility.AllocateHiddenConsole(); @@ -554,7 +533,7 @@ namespace System.Management.Automation _isRunningInBackground = true; if (startInfo.UseShellExecute == false) { - _isRunningInBackground = IsWindowsApplication; + _isRunningInBackground = isWindowsApplication; } } @@ -952,23 +931,13 @@ namespace System.Management.Automation #region checkForConsoleApplication - /// - /// Return true if the passed in process is a console process. - /// - /// - /// - private static bool CheckIfConsoleApplication(string fileName) - { - return !CheckIfWindowsApplication(fileName); - } - /// /// Check if the passed in process is a windows application. /// /// /// [ArchitectureSensitive] - private static bool CheckIfWindowsApplication(string fileName) + private static bool IsWindowsApplication(string fileName) { #if UNIX return false; @@ -1227,10 +1196,11 @@ namespace System.Management.Automation /// /// This method calculates if input and output of the process are redirected. /// + /// /// /// /// - private void CalculateIORedirection(out bool redirectOutput, out bool redirectError, out bool redirectInput) + private void CalculateIORedirection(bool isWindowsApplication, out bool redirectOutput, out bool redirectError, out bool redirectInput) { redirectInput = this.Command.MyInvocation.ExpectingInput; redirectOutput = true; @@ -1301,7 +1271,7 @@ namespace System.Management.Automation redirectOutput = true; redirectError = true; } - else if (Platform.IsWindowsDesktop && IsConsoleApplication) + else if (Platform.IsWindowsDesktop && !isWindowsApplication) { // On Windows desktops, if the command to run is a console application, // then allocate a console if there isn't one attached already... diff --git a/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 b/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 index 1372455603..95eb59857a 100644 --- a/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 +++ b/test/powershell/Language/Scripting/NativeExecution/NativeCommandProcessor.Tests.ps1 @@ -144,6 +144,15 @@ Describe "Native Command Processor" -tags "Feature" { It '$ErrorActionPreference does not apply to redirected stderr output' -Skip:(!$EnabledExperimentalFeatures.Contains('PSNotApplyErrorActionToStderr')) { pwsh -noprofile -command '$ErrorActionPreference = ''Stop''; testexe -stderr stop 2>$null; ''hello''; $error; $?' | Should -BeExactly 'hello','True' } + + It 'Can start an elevated associated process correctly' -Skip:( + !$IsWindows -or (!(Test-Path (Join-Path -Path $env:windir -ChildPath 'system32' -AdditionalChildPath 'diskmgmt.msc'))) + ) { + # test bug https://github.com/PowerShell/PowerShell/issues/13744 where console is blocked + diskmgmt.msc + Wait-UntilTrue -sb { (Get-Process mmc).Count -gt 0 } -TimeoutInMilliseconds 5000 -IntervalInMilliseconds 1000 | Should -BeTrue + Get-Process mmc | Stop-Process + } } Describe "Open a text file with NativeCommandProcessor" -tags @("Feature", "RequireAdminOnWindows") {