From 80486044d85d465b2ab6ced64da2424c904d2544 Mon Sep 17 00:00:00 2001 From: Andrew Schwartzmeyer Date: Wed, 29 Jun 2016 14:08:53 -0700 Subject: [PATCH] Guard use of throwable APIs in System.Console This is reconciled with the .NET Core 1.0 Unix ConsolePal implementation, with additional error handling for when System.Console returns unusable values. --- .../host/msh/ConsoleHostRawUserInterface.cs | 109 +++++++++--------- 1 file changed, 52 insertions(+), 57 deletions(-) diff --git a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs index 04cc4436f9..afd050e747 100644 --- a/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs +++ b/src/Microsoft.PowerShell.ConsoleHost/host/msh/ConsoleHostRawUserInterface.cs @@ -1541,7 +1541,14 @@ namespace Microsoft.PowerShell /// public override ConsoleColor BackgroundColor { - get { return Console.BackgroundColor; } + get + { + // Console can return UnknownColor, a private enum, equivalent + // to -1. When this is a case, map it instead to our default. + return Console.BackgroundColor == (ConsoleColor)(-1) + ? defaultBackground + : Console.BackgroundColor; + } set { Console.BackgroundColor = value; } } @@ -1549,32 +1556,23 @@ namespace Microsoft.PowerShell private static Size WrapSize = new Size(80, 40); /// - /// Gets or sets the size of the host buffer. In this example the - /// buffer size is adapted from the Console buffer size members. + /// Gets or sets the size of the host buffer. /// public override Size BufferSize { get { - // When stdout is redirected, the buffer size is (0, 0); - // however, this is still queried for use in formatting, so we - // provide the WrapSize. - if (Console.IsOutputRedirected) - { - return WrapSize; - } - else - { - return new Size(Console.BufferWidth, Console.BufferHeight); - } + // Console can return zero when a pseduo-TTY is allocated, which + // is useless for us. Instead, map to the wrap size. + return Console.BufferWidth == 0 || Console.BufferHeight == 0 + ? WrapSize + : new Size(Console.BufferWidth, Console.BufferHeight); } set { Console.SetBufferSize(value.Width, value.Height); } } /// - /// Gets or sets the cursor position. In this example this - /// functionality is not needed so the property throws a - /// NotImplementException exception. + /// Gets or sets the cursor position. /// public override Coordinates CursorPosition { @@ -1583,9 +1581,8 @@ namespace Microsoft.PowerShell } /// - /// Gets or sets the size of the displayed cursor. In this example - /// the cursor size is taken directly from the Console.CursorSize - /// property. + /// Gets or sets the size of the displayed cursor. + /// This maps to the corresponding Console.CursorSize property. /// public override int CursorSize { @@ -1595,11 +1592,18 @@ namespace Microsoft.PowerShell /// /// Gets or sets the foreground color of the displayed text. - /// This maps to the corresponding Console.ForgroundColor property. + /// This maps to the corresponding Console.ForegroundColor property. /// public override ConsoleColor ForegroundColor { - get { return Console.ForegroundColor; } + get + { + // Console can return UnknownColor, a private enum, equivalent + // to -1. When this is a case, map it instead to our default. + return Console.ForegroundColor == (ConsoleColor)(-1) + ? defaultForeground + : Console.ForegroundColor; + } set { Console.ForegroundColor = value; } } @@ -1613,32 +1617,37 @@ namespace Microsoft.PowerShell } /// - /// Gets the dimensions of the largest window that could be - /// rendered in the current display, if the buffer was at the least - /// that large. This example uses the Console.LargestWindowWidth and - /// Console.LargestWindowHeight properties to determine the returned - /// value of this property. + /// Gets the dimensions of the largest window that could be rendered in + /// the current display, if the buffer was at the least that large. + /// This maps to the MaxWindowSize. /// public override Size MaxPhysicalWindowSize { - get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } + get { return MaxWindowSize; } } /// - /// Gets the dimentions of the largest window size that can be - /// displayed. This example uses the Console.LargestWindowWidth and - /// console.LargestWindowHeight properties to determine the returned + /// Gets the dimensions of the largest window size that can be + /// displayed. This maps to the Console.LargestWindowWidth and + /// Console.LargestWindowHeight properties to determine the returned /// value of this property. /// public override Size MaxWindowSize { - get { return new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); } + get + { + // Console can return zero when a pseduo-TTY is allocated, which + // is useless for us. Instead, map to the wrap size. + return Console.LargestWindowWidth == 0 || Console.LargestWindowHeight == 0 + ? WrapSize + : new Size(Console.LargestWindowWidth, Console.LargestWindowHeight); + } } /// - /// Gets or sets the position of the displayed window. This example - /// uses the Console window position APIs to determine the returned - /// value of this property. + /// Gets or sets the position of the displayed window. This maps to the + /// Console window position APIs to determine the returned value of this + /// property. /// public override Coordinates WindowPosition { @@ -1655,14 +1664,11 @@ namespace Microsoft.PowerShell { get { - if (Console.IsOutputRedirected) - { - return WrapSize; - } - else - { - return new Size(Console.WindowWidth, Console.WindowHeight); - } + // Console can return zero when a pseduo-TTY is allocated, which + // is useless for us. Instead, map to the wrap size. + return Console.WindowWidth == 0 || Console.WindowHeight == 0 + ? WrapSize + : new Size(Console.WindowWidth, Console.WindowHeight); } set { Console.SetWindowSize(value.Width, value.Height); } } @@ -1680,20 +1686,9 @@ namespace Microsoft.PowerShell { get { - // In Unix/Linux systems, Console.Title current results in a not-implemented - // exception. In that case, we return a cached copy of title that was set earlier. - // Obviously, this will not work if: 1) Title was never set in PowerShell, or 2) - // one sets the windows's title outside of PowerShell. - string result; - try - { - result = Console.Title; - } - catch (PlatformNotSupportedException) - { - return title; - } - return result; + // Console throws an exception on Unix platforms, so we handle + // caching and returning the Window title ourselves. + return Platform.IsWindows ? Console.Title : title; } set