/// <summary> /// Entry point - called from the PowerShell function PSConsoleHostReadline /// after the prompt has been displayed. /// </summary> /// <returns>The complete command line.</returns> public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics) { var console = _singleton._console; _singleton._prePSReadlineConsoleMode = console.GetConsoleInputMode(); bool firstTime = true; while (true) { try { // Clear a couple flags so we can actually receive certain keys: // ENABLE_PROCESSED_INPUT - enables Ctrl+C // ENABLE_LINE_INPUT - enables Ctrl+S // Also clear a couple flags so we don't mask the input that we ignore: // ENABLE_MOUSE_INPUT - mouse events // ENABLE_WINDOW_INPUT - window resize events var mode = _singleton._prePSReadlineConsoleMode & ~(NativeMethods.ENABLE_PROCESSED_INPUT | NativeMethods.ENABLE_LINE_INPUT | NativeMethods.ENABLE_WINDOW_INPUT | NativeMethods.ENABLE_MOUSE_INPUT); console.SetConsoleInputMode(mode); if (firstTime) { firstTime = false; _singleton.Initialize(runspace, engineIntrinsics); } return(_singleton.InputLoop()); } catch (OperationCanceledException) { // Console is exiting - return value isn't too critical - null or 'exit' could work equally well. return(""); } catch (ExitException) { return("exit"); } catch (CustomHandlerException e) { var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine( string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message)); console.ForegroundColor = oldColor; var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } catch (Exception e) { // If we're running tests, just throw. if (_singleton._mockableMethods != _singleton) { throw; } while (e.InnerException != null) { e = e.InnerException; } var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine(PSReadLineResources.OopsAnErrorMessage1); console.ForegroundColor = oldColor; var sb = new StringBuilder(); for (int i = 0; i < _lastNKeys.Count; i++) { sb.Append(' '); sb.Append(_lastNKeys[i].ToGestureString()); KeyHandler handler; if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out handler) && "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase)) { // Make it a little easier to see the keys sb.Append('\n'); } } console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e)); var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } finally { console.SetConsoleInputMode(_singleton._prePSReadlineConsoleMode); } } }
/// <summary> /// Entry point - called by custom PSHost implementations that require the /// ability to cancel ReadLine. /// </summary> /// <returns>The complete command line.</returns> public static string ReadLine( Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken, bool?lastRunStatus) { var console = _singleton._console; if (Console.IsInputRedirected || Console.IsOutputRedirected) { // System.Console doesn't handle redirected input. It matches the behavior on Windows // by throwing an "InvalidOperationException". // Therefore, if either stdin or stdout is redirected, PSReadLine doesn't really work, // so throw and let PowerShell call Console.ReadLine or do whatever else it decides to do. // // Some CI environments redirect stdin/stdout, but that doesn't affect our test runs // because the console is mocked, so we can skip the exception. if (!IsRunningCI(console)) { throw new NotSupportedException(); } } var oldControlCAsInput = false; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PlatformWindows.Init(ref _singleton._charMap); } else { try { oldControlCAsInput = Console.TreatControlCAsInput; Console.TreatControlCAsInput = true; } catch {} } if (lastRunStatus.HasValue) { _singleton.ReportExecutionStatus(lastRunStatus.Value); } bool firstTime = true; while (true) { try { if (firstTime) { firstTime = false; _singleton.Initialize(runspace, engineIntrinsics); } _singleton._cancelReadCancellationToken = cancellationToken; _singleton._requestKeyWaitHandles[2] = _singleton._cancelReadCancellationToken.WaitHandle; return(_singleton.InputLoop()); } catch (OperationCanceledException) { // Console is either exiting or the cancellation of ReadLine has been requested // by a custom PSHost implementation. return(""); } catch (ExitException) { return("exit"); } catch (CustomHandlerException e) { var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine( string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message)); console.ForegroundColor = oldColor; var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } catch (Exception e) { // If we're running tests, just throw. if (_singleton._mockableMethods != _singleton) { throw; } while (e.InnerException != null) { e = e.InnerException; } var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine(PSReadLineResources.OopsAnErrorMessage1); console.ForegroundColor = oldColor; var sb = new StringBuilder(); for (int i = 0; i < _lastNKeys.Count; i++) { sb.Append(' '); sb.Append(_lastNKeys[i].KeyStr); if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out var handler) && "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase)) { // Make it a little easier to see the keys sb.Append('\n'); } } var psVersion = PSObject.AsPSObject(engineIntrinsics.Host.Version).ToString(); var ourVersion = typeof(PSConsoleReadLine).Assembly.GetCustomAttributes <AssemblyInformationalVersionAttribute>().First().InformationalVersion; var osInfo = RuntimeInformation.OSDescription; var bufferWidth = console.BufferWidth; var bufferHeight = console.BufferHeight; console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, ourVersion, psVersion, osInfo, bufferWidth, bufferHeight, _lastNKeys.Count, sb, e)); var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } finally { try { // If we are closing, restoring the old console settings isn't needed, // and some operating systems, it can cause a hang. if (!_singleton._closingWaitHandle.WaitOne(0)) { console.OutputEncoding = _singleton._initialOutputEncoding; bool IsValid(ConsoleColor color) { return(color >= ConsoleColor.Black && color <= ConsoleColor.White); } if (IsValid(_singleton._initialForeground)) { console.ForegroundColor = _singleton._initialForeground; } if (IsValid(_singleton._initialBackground)) { console.BackgroundColor = _singleton._initialBackground; } if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.TreatControlCAsInput = oldControlCAsInput; } } } catch { } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PlatformWindows.Complete(); } } } }
/// <summary> /// Entry point - called from the PowerShell function PSConsoleHostReadLine /// after the prompt has been displayed. /// </summary> /// <returns>The complete command line.</returns> public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics) { var console = _singleton._console; var oldControlCAsInput = false; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PlatformWindows.Init(ref _singleton._charMap); } else { try { oldControlCAsInput = Console.TreatControlCAsInput; Console.TreatControlCAsInput = true; } catch {} } bool firstTime = true; while (true) { try { if (firstTime) { firstTime = false; _singleton.Initialize(runspace, engineIntrinsics); } return(_singleton.InputLoop()); } catch (OperationCanceledException) { // Console is exiting - return value isn't too critical - null or 'exit' could work equally well. return(""); } catch (ExitException) { return("exit"); } catch (CustomHandlerException e) { var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine( string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message)); console.ForegroundColor = oldColor; var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } catch (Exception e) { // If we're running tests, just throw. if (_singleton._mockableMethods != _singleton) { throw; } while (e.InnerException != null) { e = e.InnerException; } var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine(PSReadLineResources.OopsAnErrorMessage1); console.ForegroundColor = oldColor; var sb = new StringBuilder(); for (int i = 0; i < _lastNKeys.Count; i++) { sb.Append(' '); sb.Append(_lastNKeys[i].ToGestureString()); if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out var handler) && "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase)) { // Make it a little easier to see the keys sb.Append('\n'); } } console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e)); var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } finally { try { // If we are closing, restoring the old console settings isn't needed, // and some operating systems, it can cause a hang. if (!_singleton._closingWaitHandle.WaitOne(0)) { console.OutputEncoding = _singleton._initialOutputEncoding; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.TreatControlCAsInput = oldControlCAsInput; } } } catch { } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PlatformWindows.Complete(); } } } }
/// <summary> /// Entry point - called from the PowerShell function PSConsoleHostReadline /// after the prompt has been displayed. /// </summary> /// <returns>The complete command line.</returns> public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics) { var console = _singleton._console; // If either stdin or stdout is redirected, PSReadline doesn't really work, so throw // and let PowerShell call Console.ReadLine or do whatever else it decides to do. if (Console.IsInputRedirected || Console.IsOutputRedirected) { throw new NotSupportedException(); } _singleton._savedConsoleInputMode = _singleton._console.GetConsoleInputMode(); bool firstTime = true; while (true) { try { _singleton._console.SetConsoleInputMode(_singleton._savedConsoleInputMode); if (firstTime) { firstTime = false; _singleton.Initialize(runspace, engineIntrinsics); } return(_singleton.InputLoop()); } catch (OperationCanceledException) { // Console is exiting - return value isn't too critical - null or 'exit' could work equally well. return(""); } catch (ExitException) { return("exit"); } catch (CustomHandlerException e) { var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine( string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message)); console.ForegroundColor = oldColor; var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } catch (Exception e) { // If we're running tests, just throw. if (_singleton._mockableMethods != _singleton) { throw; } while (e.InnerException != null) { e = e.InnerException; } var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine(PSReadLineResources.OopsAnErrorMessage1); console.ForegroundColor = oldColor; var sb = new StringBuilder(); for (int i = 0; i < _lastNKeys.Count; i++) { sb.Append(' '); sb.Append(_lastNKeys[i].ToGestureString()); KeyHandler handler; if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out handler) && "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase)) { // Make it a little easier to see the keys sb.Append('\n'); } } console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e)); var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } finally { _singleton._console.RestoreConsoleInputMode(_singleton._savedConsoleInputMode); } } }
/// <summary> /// Entry point - called by custom PSHost implementations that require the /// ability to cancel ReadLine. /// </summary> /// <returns>The complete command line.</returns> public static string ReadLine(Runspace runspace, EngineIntrinsics engineIntrinsics, CancellationToken cancellationToken) { var console = _singleton._console; var oldControlCAsInput = false; if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PlatformWindows.Init(ref _singleton._charMap); } else { if (Console.IsInputRedirected || Console.IsOutputRedirected) { // System.Console doesn't handle redirected input. It matches the behavior on Windows // by throwing an "InvalidOperationException". // Therefore, if either stdin or stdout is redirected, PSReadLine doesn't really work, // so throw and let PowerShell call Console.ReadLine or do whatever else it decides to do. throw new NotSupportedException(); } try { oldControlCAsInput = Console.TreatControlCAsInput; Console.TreatControlCAsInput = true; } catch {} } bool firstTime = true; while (true) { try { if (firstTime) { firstTime = false; _singleton.Initialize(runspace, engineIntrinsics); } _singleton._cancelReadCancellationToken = cancellationToken; _singleton._requestKeyWaitHandles[2] = _singleton._cancelReadCancellationToken.WaitHandle; return(_singleton.InputLoop()); } catch (OperationCanceledException) { // Console is either exiting or the cancellation of ReadLine has been requested // by a custom PSHost implementation. return(""); } catch (ExitException) { return("exit"); } catch (CustomHandlerException e) { var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine( string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsCustomHandlerException, e.InnerException.Message)); console.ForegroundColor = oldColor; var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } catch (Exception e) { // If we're running tests, just throw. if (_singleton._mockableMethods != _singleton) { throw; } while (e.InnerException != null) { e = e.InnerException; } var oldColor = console.ForegroundColor; console.ForegroundColor = ConsoleColor.Red; console.WriteLine(PSReadLineResources.OopsAnErrorMessage1); console.ForegroundColor = oldColor; var sb = new StringBuilder(); for (int i = 0; i < _lastNKeys.Count; i++) { sb.Append(' '); sb.Append(_lastNKeys[i].ToGestureString()); if (_singleton._dispatchTable.TryGetValue(_lastNKeys[i], out var handler) && "AcceptLine".Equals(handler.BriefDescription, StringComparison.OrdinalIgnoreCase)) { // Make it a little easier to see the keys sb.Append('\n'); } } console.WriteLine(string.Format(CultureInfo.CurrentUICulture, PSReadLineResources.OopsAnErrorMessage2, _lastNKeys.Count, sb, e)); var lineBeforeCrash = _singleton._buffer.ToString(); _singleton.Initialize(runspace, _singleton._engineIntrinsics); InvokePrompt(); Insert(lineBeforeCrash); } finally { try { // If we are closing, restoring the old console settings isn't needed, // and some operating systems, it can cause a hang. if (!_singleton._closingWaitHandle.WaitOne(0)) { console.OutputEncoding = _singleton._initialOutputEncoding; if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { Console.TreatControlCAsInput = oldControlCAsInput; } } } catch { } if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { PlatformWindows.Complete(); } } } }