Enable PSReadline to work on NanoServer (#3815)
NanoServer is missing some console APIs that PSReadline uses which causes PSReadline to not be usable on NanoServer docker images. For the missing font/display APIs, the fix is to assume all characters use 1 cell which is not always correct for some languages. For the missing keymap APIs - there is no workaround in this change and a small number of key bindings don't work, there is an open issue to track those. Fixes #3463
This commit is contained in:
parent
51d4a45e3c
commit
ee45650660
|
@ -1,4 +1,4 @@
|
|||
/********************************************************************++
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
|
@ -231,7 +231,6 @@ namespace Microsoft.PowerShell
|
|||
return valid;
|
||||
}
|
||||
|
||||
#if UNIX
|
||||
// this is borrowed from the CoreFX internal System.IO.StdInReader class
|
||||
// https://github.com/dotnet/corefx/blob/5b2ae6aa485773cd5569f56f446698633c9ad945/src/System.Console/src/System/IO/StdInReader.cs#L222
|
||||
private static ConsoleKey GetKeyFromCharValue(char x, out bool isShift, out bool isCtrl)
|
||||
|
@ -303,7 +302,8 @@ namespace Microsoft.PowerShell
|
|||
|
||||
return default(ConsoleKey);
|
||||
}
|
||||
#else
|
||||
|
||||
#if !UNIX
|
||||
internal static char GetCharFromConsoleKey(ConsoleKey key, ConsoleModifiers modifiers)
|
||||
{
|
||||
// default for unprintables and unhandled
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/********************************************************************++
|
||||
/********************************************************************++
|
||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
--********************************************************************/
|
||||
|
||||
|
@ -370,6 +370,23 @@ namespace Microsoft.PowerShell.Internal
|
|||
|
||||
internal static class ConsoleKeyInfoExtension
|
||||
{
|
||||
#if !UNIX
|
||||
private static bool _toUnicodeApiAvailable = true;
|
||||
|
||||
static ConsoleKeyInfoExtension()
|
||||
{
|
||||
try
|
||||
{
|
||||
var chars = new char[2];
|
||||
NativeMethods.ToUnicode(13, 28, null, chars, chars.Length, 0);
|
||||
}
|
||||
catch (System.EntryPointNotFoundException)
|
||||
{
|
||||
_toUnicodeApiAvailable = false; // api not available on NanoServer
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
public static string ToGestureString(this ConsoleKeyInfo key)
|
||||
{
|
||||
var mods = key.Modifiers;
|
||||
|
@ -386,13 +403,16 @@ namespace Microsoft.PowerShell.Internal
|
|||
sb.Append("Alt");
|
||||
}
|
||||
|
||||
#if UNIX
|
||||
char c = key.KeyChar;
|
||||
#else
|
||||
// Windows cannot use KeyChar as some chords (like Ctrl+[) show up as control characters.
|
||||
char c = ConsoleKeyChordConverter.GetCharFromConsoleKey(key.Key,
|
||||
(mods & ConsoleModifiers.Shift) != 0 ? ConsoleModifiers.Shift : 0);
|
||||
#if !UNIX
|
||||
if (_toUnicodeApiAvailable)
|
||||
{
|
||||
// Windows cannot use KeyChar as some chords (like Ctrl+[) show up as control characters.
|
||||
c = ConsoleKeyChordConverter.GetCharFromConsoleKey(key.Key,
|
||||
(mods & ConsoleModifiers.Shift) != 0 ? ConsoleModifiers.Shift : 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (char.IsControl(c) || char.IsWhiteSpace(c))
|
||||
{
|
||||
if (key.Modifiers.HasFlag(ConsoleModifiers.Shift))
|
||||
|
@ -426,6 +446,7 @@ namespace Microsoft.PowerShell.Internal
|
|||
private bool _istmInitialized = false;
|
||||
private TEXTMETRIC _tm = new TEXTMETRIC();
|
||||
private bool _trueTypeInUse = false;
|
||||
private static bool _getCurrentConsoleFontExApiAvailable = true;
|
||||
|
||||
private readonly Lazy<SafeFileHandle> _outputHandle = new Lazy<SafeFileHandle>(() =>
|
||||
{
|
||||
|
@ -691,7 +712,18 @@ namespace Microsoft.PowerShell.Internal
|
|||
|
||||
CONSOLE_FONT_INFO_EX fontInfo = new CONSOLE_FONT_INFO_EX();
|
||||
fontInfo.cbSize = Marshal.SizeOf(fontInfo);
|
||||
bool result = NativeMethods.GetCurrentConsoleFontEx(consoleHandle.DangerousGetHandle(), false, ref fontInfo);
|
||||
bool result = true;
|
||||
if (_getCurrentConsoleFontExApiAvailable)
|
||||
{
|
||||
try
|
||||
{
|
||||
result = NativeMethods.GetCurrentConsoleFontEx(consoleHandle.DangerousGetHandle(), false, ref fontInfo);
|
||||
}
|
||||
catch (System.EntryPointNotFoundException)
|
||||
{
|
||||
_getCurrentConsoleFontExApiAvailable = false; // api not available on NanoServer
|
||||
}
|
||||
}
|
||||
|
||||
if (result == false)
|
||||
{
|
||||
|
@ -865,7 +897,6 @@ namespace Microsoft.PowerShell.Internal
|
|||
CONSOLE_FONT_INFO_EX fontInfo = ConhostConsole.GetConsoleFontInfo(consoleHandle);
|
||||
int fontType = fontInfo.FontFamily & NativeMethods.FontTypeMask;
|
||||
_trueTypeInUse = (fontType & NativeMethods.TrueTypeFont) == NativeMethods.TrueTypeFont;
|
||||
|
||||
}
|
||||
|
||||
public void EndRender()
|
||||
|
|
Loading…
Reference in a new issue