@@ -45,6 +45,10 @@ public SynchronousPowerShellTask(
4545
4646 public override ExecutionOptions ExecutionOptions => PowerShellExecutionOptions ;
4747
48+ // These are PowerShell's intrinsic debugger commands that must be run via
49+ // `ProcessDebugCommand`.
50+ private static readonly string [ ] DebuggerCommands = { "continue" , "c" , "k" , "h" , "?" , "list" , "l" , "stepInto" , "s" , "stepOut" , "o" , "stepOver" , "v" , "quit" , "q" , "detach" , "d" } ;
51+
4852 public override IReadOnlyList < TResult > Run ( CancellationToken cancellationToken )
4953 {
5054 _pwsh = _psesHost . CurrentPowerShell ;
@@ -55,6 +59,9 @@ public override IReadOnlyList<TResult> Run(CancellationToken cancellationToken)
5559 }
5660
5761 return _pwsh . Runspace . Debugger . InBreakpoint
62+ && Array . Exists (
63+ DebuggerCommands ,
64+ c => c . Equals ( _psCommand . GetInvocationText ( ) , StringComparison . CurrentCultureIgnoreCase ) )
5865 ? ExecuteInDebugger ( cancellationToken )
5966 : ExecuteNormally ( cancellationToken ) ;
6067 }
@@ -89,9 +96,15 @@ private IReadOnlyList<TResult> ExecuteNormally(CancellationToken cancellationTok
8996 result = _pwsh . InvokeCommand < TResult > ( _psCommand , invocationSettings ) ;
9097 cancellationToken . ThrowIfCancellationRequested ( ) ;
9198 }
92- // Test if we've been cancelled. If we're remoting, PSRemotingDataStructureException effectively means the pipeline was stopped.
99+ // Test if we've been cancelled. If we're remoting, PSRemotingDataStructureException
100+ // effectively means the pipeline was stopped.
93101 catch ( Exception e ) when ( cancellationToken . IsCancellationRequested || e is PipelineStoppedException || e is PSRemotingDataStructureException )
94102 {
103+ // ExecuteNormally handles user commands in a debug session. Perhaps we should clean all this up somehow.
104+ if ( _pwsh . Runspace . Debugger . InBreakpoint )
105+ {
106+ StopDebuggerIfRemoteDebugSessionFailed ( ) ;
107+ }
95108 throw new OperationCanceledException ( ) ;
96109 }
97110 // We only catch RuntimeExceptions here in case writing errors to output was requested
@@ -124,6 +137,8 @@ private IReadOnlyList<TResult> ExecuteNormally(CancellationToken cancellationTok
124137
125138 private IReadOnlyList < TResult > ExecuteInDebugger ( CancellationToken cancellationToken )
126139 {
140+ // TODO: How much of this method can we remove now that it only processes PowerShell's
141+ // intrinsic debugger commands?
127142 cancellationToken . Register ( CancelDebugExecution ) ;
128143
129144 var outputCollection = new PSDataCollection < PSObject > ( ) ;
@@ -148,14 +163,22 @@ private IReadOnlyList<TResult> ExecuteInDebugger(CancellationToken cancellationT
148163 DebuggerCommandResults debuggerResult = null ;
149164 try
150165 {
151- // In the PowerShell debugger, extra debugger commands are made available, like "l", "s", "c", etc.
152- // Executing those commands produces a result that needs to be set on the debugger stop event args.
153- // So we use the Debugger.ProcessCommand() API to properly execute commands in the debugger
154- // and then call DebugContext.ProcessDebuggerResult() later to handle the command appropriately
166+ // In the PowerShell debugger, intrinsic debugger commands are made available, like
167+ // "l", "s", "c", etc. Executing those commands produces a result that needs to be
168+ // set on the debugger stop event args. So we use the Debugger.ProcessCommand() API
169+ // to properly execute commands in the debugger and then call
170+ // DebugContext.ProcessDebuggerResult() later to handle the command appropriately
171+ //
172+ // Unfortunately, this API does not allow us to pass in the InvocationSettings,
173+ // which means (for instance) that we cannot instruct it to avoid adding our
174+ // debugger implmentation's commands to the history. So instead we now only call
175+ // `ExecuteInDebugger` for PowerShell's own intrinsic debugger commands.
155176 debuggerResult = _pwsh . Runspace . Debugger . ProcessCommand ( _psCommand , outputCollection ) ;
156177 cancellationToken . ThrowIfCancellationRequested ( ) ;
157178 }
158- // Test if we've been cancelled. If we're remoting, PSRemotingDataStructureException effectively means the pipeline was stopped.
179+
180+ // Test if we've been cancelled. If we're remoting, PSRemotingDataStructureException
181+ // effectively means the pipeline was stopped.
159182 catch ( Exception e ) when ( cancellationToken . IsCancellationRequested || e is PipelineStoppedException || e is PSRemotingDataStructureException )
160183 {
161184 StopDebuggerIfRemoteDebugSessionFailed ( ) ;
0 commit comments