@@ -25,11 +25,14 @@ public class DebugAdapter : DebugAdapterBase
2525 private EditorSession editorSession ;
2626
2727 private bool noDebug ;
28+ private bool isRemoteAttach ;
2829 private bool isAttachSession ;
2930 private bool waitingForAttach ;
3031 private string scriptToLaunch ;
3132 private bool ownsEditorSession ;
33+ private bool executionCompleted ;
3234 private string arguments ;
35+ private RequestContext < object > disconnectRequestContext = null ;
3336
3437 public DebugAdapter ( HostDetails hostDetails , ProfilePaths profilePaths )
3538 : this ( hostDetails , profilePaths , new StdioServerChannel ( ) , null )
@@ -90,17 +93,57 @@ protected Task LaunchScript(RequestContext<object> requestContext)
9093 {
9194 return editorSession . PowerShellContext
9295 . ExecuteScriptWithArgs ( this . scriptToLaunch , this . arguments )
93- . ContinueWith (
94- async ( t ) => {
95- Logger . Write ( LogLevel . Verbose , "Execution completed, flushing output then terminating..." ) ;
96+ . ContinueWith ( this . OnExecutionCompleted ) ;
97+ }
98+
99+ private async Task OnExecutionCompleted ( Task executeTask )
100+ {
101+ Logger . Write ( LogLevel . Verbose , "Execution completed, terminating..." ) ;
102+
103+ this . executionCompleted = true ;
104+
105+ if ( this . isAttachSession )
106+ {
107+ // Ensure the read loop is stopped
108+ this . editorSession . ConsoleService . CancelReadLoop ( ) ;
109+
110+ // Pop the sessions
111+ if ( this . editorSession . PowerShellContext . CurrentRunspace . Context == RunspaceContext . EnteredProcess )
112+ {
113+ try
114+ {
115+ await this . editorSession . PowerShellContext . ExecuteScriptString ( "Exit-PSHostProcess" ) ;
116+
117+ if ( this . isRemoteAttach &&
118+ this . editorSession . PowerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
119+ {
120+ await this . editorSession . PowerShellContext . ExecuteScriptString ( "Exit-PSSession" ) ;
121+ }
122+ }
123+ catch ( Exception e )
124+ {
125+ Logger . WriteException ( "Caught exception while popping attached process after debugging" , e ) ;
126+ }
127+ }
96128
97- await this . SendEvent (
98- TerminatedEvent . Type ,
99- new TerminatedEvent ( ) ) ;
129+ if ( ! this . ownsEditorSession )
130+ {
131+ this . editorSession . ConsoleService . StartReadLoop ( ) ;
132+ }
133+ }
100134
101- // Stop the server
102- await this . Stop ( ) ;
103- } ) ;
135+ if ( this . disconnectRequestContext != null )
136+ {
137+ // Respond to the disconnect request and stop the server
138+ await this . disconnectRequestContext . SendResult ( null ) ;
139+ await this . Stop ( ) ;
140+ }
141+ else
142+ {
143+ await this . SendEvent (
144+ TerminatedEvent . Type ,
145+ new TerminatedEvent ( ) ) ;
146+ }
104147 }
105148
106149 protected override void Shutdown ( )
@@ -214,9 +257,9 @@ protected async Task HandleLaunchRequest(
214257 // machine if necessary
215258 if ( this . editorSession . PowerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
216259 {
217- this . scriptPathToLaunch =
260+ this . scriptToLaunch =
218261 this . editorSession . RemoteFileManager . GetMappedPath (
219- this . scriptPathToLaunch ,
262+ this . scriptToLaunch ,
220263 this . editorSession . PowerShellContext . CurrentRunspace ) ;
221264 }
222265
@@ -273,6 +316,13 @@ await requestContext.SendError(
273316
274317 return ;
275318 }
319+ else if ( this . editorSession . PowerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
320+ {
321+ await requestContext . SendError (
322+ $ "Cannot attach to a process in a remote session when already in a remote session.") ;
323+
324+ return ;
325+ }
276326
277327 await this . editorSession . PowerShellContext . ExecuteScriptString (
278328 $ "Enter-PSSession -ComputerName \" { attachParams . ComputerName } \" ",
@@ -285,6 +335,8 @@ await requestContext.SendError(
285335
286336 return ;
287337 }
338+
339+ this . isRemoteAttach = true ;
288340 }
289341
290342 if ( int . TryParse ( attachParams . ProcessId , out int processId ) && ( processId > 0 ) )
@@ -319,8 +371,9 @@ await requestContext.SendError(
319371 int runspaceId = attachParams . RunspaceId > 0 ? attachParams . RunspaceId : 1 ;
320372 this . waitingForAttach = true ;
321373 Task nonAwaitedTask =
322- this . editorSession . PowerShellContext . ExecuteScriptString (
323- $ "\n Debug-Runspace -Id { runspaceId } ") ;
374+ this . editorSession . PowerShellContext
375+ . ExecuteScriptString ( $ "\n Debug-Runspace -Id { runspaceId } ")
376+ . ContinueWith ( this . OnExecutionCompleted ) ;
324377 }
325378 else
326379 {
@@ -341,40 +394,13 @@ protected async Task HandleDisconnectRequest(
341394 object disconnectParams ,
342395 RequestContext < object > requestContext )
343396 {
344- EventHandler < SessionStateChangedEventArgs > handler = null ;
345-
346- // Define a handler that encapsulates the RequestContext so
347- // that it can be completed once the executed script is
348- // shutting down.
349- handler =
350- async ( o , e ) =>
351- {
352- if ( e . NewSessionState == PowerShellContextState . Ready )
353- {
354- await requestContext . SendResult ( null ) ;
355- this . editorSession . PowerShellContext . SessionStateChanged -= handler ;
356-
357- if ( this . isAttachSession )
358- {
359- // Start up the read loop again if this is a shared session
360- if ( ! this . ownsEditorSession )
361- {
362- this . editorSession . ConsoleService . StartReadLoop ( ) ;
363- }
364-
365- await this . Stop ( ) ;
366- }
367- }
368- } ;
369-
370397 // In some rare cases, the EditorSession will already be disposed
371398 // so we shouldn't try to abort because PowerShellContext will be null
372399 if ( this . editorSession != null && this . editorSession . PowerShellContext != null )
373400 {
374- if ( this . editorSession . PowerShellContext . SessionState == PowerShellContextState . Running ||
375- this . editorSession . PowerShellContext . IsDebuggerStopped )
401+ if ( this . executionCompleted == false )
376402 {
377- this . editorSession . PowerShellContext . SessionStateChanged += handler ;
403+ this . disconnectRequestContext = requestContext ;
378404 this . editorSession . PowerShellContext . AbortExecution ( ) ;
379405 }
380406 else
@@ -772,7 +798,7 @@ async void powerShellContext_RunspaceChanged(object sender, RunspaceChangedEvent
772798 await this . SendEvent ( InitializedEvent . Type , null ) ;
773799 }
774800 else if (
775- e . ChangeAction == RunspaceChangeAction . Exit &&
801+ e . ChangeAction == RunspaceChangeAction . Exit &&
776802 ( this . editorSession == null ||
777803 this . editorSession . PowerShellContext . IsDebuggerStopped ) )
778804 {
0 commit comments