/// <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 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 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(); } } } }