@@ -25,11 +25,14 @@ public class DebugAdapter : DebugAdapterBase
25
25
private EditorSession editorSession ;
26
26
27
27
private bool noDebug ;
28
+ private bool isRemoteAttach ;
28
29
private bool isAttachSession ;
29
30
private bool waitingForAttach ;
30
31
private string scriptToLaunch ;
31
32
private bool ownsEditorSession ;
33
+ private bool executionCompleted ;
32
34
private string arguments ;
35
+ private RequestContext < object > disconnectRequestContext = null ;
33
36
34
37
public DebugAdapter ( HostDetails hostDetails , ProfilePaths profilePaths )
35
38
: this ( hostDetails , profilePaths , new StdioServerChannel ( ) , null )
@@ -90,17 +93,57 @@ protected Task LaunchScript(RequestContext<object> requestContext)
90
93
{
91
94
return editorSession . PowerShellContext
92
95
. 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
+ }
96
128
97
- await this . SendEvent (
98
- TerminatedEvent . Type ,
99
- new TerminatedEvent ( ) ) ;
129
+ if ( ! this . ownsEditorSession )
130
+ {
131
+ this . editorSession . ConsoleService . StartReadLoop ( ) ;
132
+ }
133
+ }
100
134
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
+ }
104
147
}
105
148
106
149
protected override void Shutdown ( )
@@ -214,9 +257,9 @@ protected async Task HandleLaunchRequest(
214
257
// machine if necessary
215
258
if ( this . editorSession . PowerShellContext . CurrentRunspace . Location == RunspaceLocation . Remote )
216
259
{
217
- this . scriptPathToLaunch =
260
+ this . scriptToLaunch =
218
261
this . editorSession . RemoteFileManager . GetMappedPath (
219
- this . scriptPathToLaunch ,
262
+ this . scriptToLaunch ,
220
263
this . editorSession . PowerShellContext . CurrentRunspace ) ;
221
264
}
222
265
@@ -273,6 +316,13 @@ await requestContext.SendError(
273
316
274
317
return ;
275
318
}
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
+ }
276
326
277
327
await this . editorSession . PowerShellContext . ExecuteScriptString (
278
328
$ "Enter-PSSession -ComputerName \" { attachParams . ComputerName } \" ",
@@ -285,6 +335,8 @@ await requestContext.SendError(
285
335
286
336
return ;
287
337
}
338
+
339
+ this . isRemoteAttach = true ;
288
340
}
289
341
290
342
if ( int . TryParse ( attachParams . ProcessId , out int processId ) && ( processId > 0 ) )
@@ -319,8 +371,9 @@ await requestContext.SendError(
319
371
int runspaceId = attachParams . RunspaceId > 0 ? attachParams . RunspaceId : 1 ;
320
372
this . waitingForAttach = true ;
321
373
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 ) ;
324
377
}
325
378
else
326
379
{
@@ -341,40 +394,13 @@ protected async Task HandleDisconnectRequest(
341
394
object disconnectParams ,
342
395
RequestContext < object > requestContext )
343
396
{
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
-
370
397
// In some rare cases, the EditorSession will already be disposed
371
398
// so we shouldn't try to abort because PowerShellContext will be null
372
399
if ( this . editorSession != null && this . editorSession . PowerShellContext != null )
373
400
{
374
- if ( this . editorSession . PowerShellContext . SessionState == PowerShellContextState . Running ||
375
- this . editorSession . PowerShellContext . IsDebuggerStopped )
401
+ if ( this . executionCompleted == false )
376
402
{
377
- this . editorSession . PowerShellContext . SessionStateChanged += handler ;
403
+ this . disconnectRequestContext = requestContext ;
378
404
this . editorSession . PowerShellContext . AbortExecution ( ) ;
379
405
}
380
406
else
@@ -772,7 +798,7 @@ async void powerShellContext_RunspaceChanged(object sender, RunspaceChangedEvent
772
798
await this . SendEvent ( InitializedEvent . Type , null ) ;
773
799
}
774
800
else if (
775
- e . ChangeAction == RunspaceChangeAction . Exit &&
801
+ e . ChangeAction == RunspaceChangeAction . Exit &&
776
802
( this . editorSession == null ||
777
803
this . editorSession . PowerShellContext . IsDebuggerStopped ) )
778
804
{
0 commit comments