public void Run()

in DbgShell/ColorConsoleHost.cs [207:434]


            public void Run()
            {
                StringBuilder sbCmd = new StringBuilder();

                while( !m_timeToStop && !m_host.ShouldExit )
                {
                    string input;
                    bool addToHistory;

                    if( _IsOutermostInputLoop && _HaveInjectedCommands )
                    {
                        // From "guest mode".
                        addToHistory = false;
                        input = sm_injectedCommands.Dequeue();
                    }
                    else
                    {
                        addToHistory = true;

                        string prompt;
                        if( 0 == sbCmd.Length )
                        {
                            prompt = m_host._GetPrompt( m_shell );
                        }
                        else
                        {
                            prompt = "\u009b97m>>\u009bm ";
                        }

                        m_host.UI.Write( prompt );

                        try
                        {
                            input = m_host.m_ui.ReadLineWithTabCompletion( true );
                        }
                        catch( PipelineStoppedException ) // thrown if calling user-defined tab completion (TODO: except we don't actually ever call user-defined tab completion yet)
                        {
                            sbCmd.Clear();
                            _ClearAutoRepeatCmd();
                            continue;
                        }
                    }

                    if( null == input )
                    {
                        // It returns null if input was canceled via CTRL-C.
                        //
                        // (and it's a good thing--if we tried to use a CtrlCInterceptor
                        // to cancel multi-line input, it wouldn't work well, because the
                        // CTRL-C thread races with the input thread)
                        sbCmd.Clear();
                        _ClearAutoRepeatCmd();
                        m_host.m_ui.WriteLine();
                        continue;
                    }

                    if( String.IsNullOrWhiteSpace( input ) )
                    {
                        if( sbCmd.Length != 0 )
                        {
                            sbCmd.Append( input ); // let's keep the whitespace for looks.
                            sbCmd.AppendLine();
                            continue;
                        }
                        else
                        {
                            if( 0 == input.Length )
                            {
                                //
                                // Someone just hit [Enter].
                                //
                                // We'll retrieve the DbgAutoRepeatCommand command.
                                //

                                if( !m_shell.IsNested )
                                {
                                    string autoRepeatCmd = m_shell.Runspace.SessionStateProxy.PSVariable.GetValue(
                                                                c_DbgAutoRepeatCmd,
                                                                null ) as string;
                                    m_shell.Runspace.SessionStateProxy.PSVariable.Set( c_DbgAutoRepeatCmd, null );
                                    sbCmd.Append( autoRepeatCmd );
                                }
                                else
                                {
                                    // Unbelievably, you cannot access session state via the Runspace.SessionStateProxy
                                    // (doing so will yield a PSInvalidOperationException: "A pipeline is already
                                    // running. Concurrent SessionStateProxy method call is not allowed.", whether you
                                    // access it from the pipeline execution thread or the main thread (that owns the
                                    // shell). So we'll get around that by just running some script to get and set the
                                    // variable.
                                    var results = m_host._ExecScriptNoExceptionHandling( m_shell,
                                                                                         Util.Sprintf( "Get-Variable {0}",
                                                                                                       c_DbgAutoRepeatCmd ),
                                                                                         false,
                                                                                         false );
                                    if( (null != results) &&
                                        (results.Count > 0) &&
                                        (results[ 0 ].BaseObject is PSVariable) )
                                    {
                                        PSVariable psvar = (PSVariable) results[ 0 ].BaseObject;
                                        if( psvar.Value is string )
                                            sbCmd.Append( (string) psvar.Value );
                                    }
                                    m_host._ExecScriptNoExceptionHandling( m_shell,
                                                                           Util.Sprintf( "Set-Variable {0} $null",
                                                                                         c_DbgAutoRepeatCmd ),
                                                                           false,
                                                                           false );
                                } // end else( nested shell )

                                if( 0 == sbCmd.Length )
                                    continue;
                            }
                            else
                            {   // input.Length != 0
                                //
                                // This is for the type-space-then-enter scenario, which
                                // windbg users use to clear the auto-run command.
                                //
                                _ClearAutoRepeatCmd();
                                continue;
                            }
                        } // end else( no multiline input )
                    } // end if( current input is empty )
#if DEBUG
                    else if( 0 == Util.Strcmp_OI( "Test-CaStringUtil", input ) )
                    {
                        CaStringUtil.SelfTest();
                        continue;
                    }
                    else if( 0 == Util.Strcmp_OI( "Test-MassageTypeName", input ) )
                    {
                        Util.TestMassageTypeName();
                        continue;
                    }
#endif
                    else
                    {
                        _ClearAutoRepeatCmd();
                        sbCmd.Append( input );
                    }

                    try
                    {
                        using( _CreateTryStopShellCtrlHandler( m_shell ) )
                        {
                            LogManager.Trace( "Attempting to execute input: {0}", sbCmd.ToString() );
                            m_host._ExecScriptNoExceptionHandling( m_shell,
                                                                   sbCmd.ToString(),
                                                                   addToHistory );
                            sbCmd.Clear();

                            //
                            // Now that the command has been executed, we'll discard any
                            // leftover progress stuff.
                            //

                            m_host.m_ui.ResetProgress();

                            if( !m_timeToStop && !m_host.ShouldExit )
                            {
                                try
                                {
                                    // If we make it back to here and the execution status is
                                    // "go", then we need to wait.
                                    //
                                    // This can happen, for instance, when DbgShell.exe is the
                                    // host (we are not in guest mode), and a breakpoint
                                    // command runs a !dbgshell command which resumes
                                    // execution. Resuming execution from the bp cmd will use
                                    // "exit" to terminate the bp cmd, and we'll end up back
                                    // here. So rather than just show another prompt, we need
                                    // to actually do the wait here.
                                    //
                                    // In the guest mode case, the "exit" causes us to
                                    // passivate, returning control to windbg (or whoever the
                                    // host is), and the host performs the wait.

                                    var execStatus = DbgEngDebugger._GlobalDebugger.GetExecutionStatus();
                                    bool statusRequiresWait = _StatusRequiresWait( execStatus );

                                    while( statusRequiresWait )
                                    {
                                        LogManager.Trace( "InputLoop.Run: current status requires we wait: {0}", execStatus );

                                        // Rather than just calling
                                        // DbgEngDebugger._GlobalDebugger.WaitForEventAsync(),
                                        // we will call a cmdlet (Resume-Process) to do the
                                        // wait for us. This will set up a pipeline so that
                                        // events can be reported, a CTRL-C handler, etc.

                                        m_host._ExecScriptNoExceptionHandling( m_shell,
                                                                               "Resume-Process -ResumeType Passive",
                                                                               addToHistory: false );

                                        execStatus = DbgEngDebugger._GlobalDebugger.GetExecutionStatus();
                                        statusRequiresWait = _StatusRequiresWait( execStatus );
                                    }
                                }
                                catch( DbgEngException dee )
                                {
                                    m_host._ReportException( dee, m_shell ); // <-- this may be a nested shell
                                }
                            } // end if( !m_timeToStop && !m_host.ShouldExit )
                        } // end using( _CreateTryStopShellCtrlHandler( m_shell ) )
                    }
                    catch( IncompleteParseException )
                    {
                        // We'll just keep appending to sbCmd.
                        sbCmd.AppendLine();
                    }
                    catch( PipelineStoppedException )
                    {
                        sbCmd.Clear();
                        // ignore
                    }
                    catch( RuntimeException rte )
                    {
                        sbCmd.Clear();
                        m_host._ReportException( rte, m_shell ); // <-- this may be a nested shell
                    }
                    catch( Exception e )
                    {
                        Util.Fail( Util.Sprintf( "What error is this? {0}", e ) );
                        sbCmd.Clear();
                    }
                } // end while( !m_timeToStop && !m_host.m_shouldExit )
            } // end Run()