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
2 changed files with 42 additions and 11 deletions
|
@ -1,4 +1,4 @@
|
||||||
/********************************************************************++
|
/********************************************************************++
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
--********************************************************************/
|
--********************************************************************/
|
||||||
|
|
||||||
|
@ -231,7 +231,6 @@ namespace Microsoft.PowerShell
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNIX
|
|
||||||
// this is borrowed from the CoreFX internal System.IO.StdInReader class
|
// 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
|
// 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)
|
private static ConsoleKey GetKeyFromCharValue(char x, out bool isShift, out bool isCtrl)
|
||||||
|
@ -303,7 +302,8 @@ namespace Microsoft.PowerShell
|
||||||
|
|
||||||
return default(ConsoleKey);
|
return default(ConsoleKey);
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
|
#if !UNIX
|
||||||
internal static char GetCharFromConsoleKey(ConsoleKey key, ConsoleModifiers modifiers)
|
internal static char GetCharFromConsoleKey(ConsoleKey key, ConsoleModifiers modifiers)
|
||||||
{
|
{
|
||||||
// default for unprintables and unhandled
|
// default for unprintables and unhandled
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/********************************************************************++
|
/********************************************************************++
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
--********************************************************************/
|
--********************************************************************/
|
||||||
|
|
||||||
|
@ -370,6 +370,23 @@ namespace Microsoft.PowerShell.Internal
|
||||||
|
|
||||||
internal static class ConsoleKeyInfoExtension
|
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)
|
public static string ToGestureString(this ConsoleKeyInfo key)
|
||||||
{
|
{
|
||||||
var mods = key.Modifiers;
|
var mods = key.Modifiers;
|
||||||
|
@ -386,13 +403,16 @@ namespace Microsoft.PowerShell.Internal
|
||||||
sb.Append("Alt");
|
sb.Append("Alt");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if UNIX
|
|
||||||
char c = key.KeyChar;
|
char c = key.KeyChar;
|
||||||
#else
|
#if !UNIX
|
||||||
|
if (_toUnicodeApiAvailable)
|
||||||
|
{
|
||||||
// Windows cannot use KeyChar as some chords (like Ctrl+[) show up as control characters.
|
// Windows cannot use KeyChar as some chords (like Ctrl+[) show up as control characters.
|
||||||
char c = ConsoleKeyChordConverter.GetCharFromConsoleKey(key.Key,
|
c = ConsoleKeyChordConverter.GetCharFromConsoleKey(key.Key,
|
||||||
(mods & ConsoleModifiers.Shift) != 0 ? ConsoleModifiers.Shift : 0);
|
(mods & ConsoleModifiers.Shift) != 0 ? ConsoleModifiers.Shift : 0);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (char.IsControl(c) || char.IsWhiteSpace(c))
|
if (char.IsControl(c) || char.IsWhiteSpace(c))
|
||||||
{
|
{
|
||||||
if (key.Modifiers.HasFlag(ConsoleModifiers.Shift))
|
if (key.Modifiers.HasFlag(ConsoleModifiers.Shift))
|
||||||
|
@ -426,6 +446,7 @@ namespace Microsoft.PowerShell.Internal
|
||||||
private bool _istmInitialized = false;
|
private bool _istmInitialized = false;
|
||||||
private TEXTMETRIC _tm = new TEXTMETRIC();
|
private TEXTMETRIC _tm = new TEXTMETRIC();
|
||||||
private bool _trueTypeInUse = false;
|
private bool _trueTypeInUse = false;
|
||||||
|
private static bool _getCurrentConsoleFontExApiAvailable = true;
|
||||||
|
|
||||||
private readonly Lazy<SafeFileHandle> _outputHandle = new Lazy<SafeFileHandle>(() =>
|
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();
|
CONSOLE_FONT_INFO_EX fontInfo = new CONSOLE_FONT_INFO_EX();
|
||||||
fontInfo.cbSize = Marshal.SizeOf(fontInfo);
|
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)
|
if (result == false)
|
||||||
{
|
{
|
||||||
|
@ -865,7 +897,6 @@ namespace Microsoft.PowerShell.Internal
|
||||||
CONSOLE_FONT_INFO_EX fontInfo = ConhostConsole.GetConsoleFontInfo(consoleHandle);
|
CONSOLE_FONT_INFO_EX fontInfo = ConhostConsole.GetConsoleFontInfo(consoleHandle);
|
||||||
int fontType = fontInfo.FontFamily & NativeMethods.FontTypeMask;
|
int fontType = fontInfo.FontFamily & NativeMethods.FontTypeMask;
|
||||||
_trueTypeInUse = (fontType & NativeMethods.TrueTypeFont) == NativeMethods.TrueTypeFont;
|
_trueTypeInUse = (fontType & NativeMethods.TrueTypeFont) == NativeMethods.TrueTypeFont;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void EndRender()
|
public void EndRender()
|
||||||
|
|
Loading…
Reference in a new issue