@@ -350,11 +350,17 @@ protected async Task HandleAttachRequestAsync(
350
350
351
351
RegisterEventHandlers ( ) ;
352
352
353
+ bool processIdIsSet = ! string . IsNullOrEmpty ( attachParams . ProcessId ) && attachParams . ProcessId != "undefined" ;
354
+ bool customPipeNameIsSet = ! string . IsNullOrEmpty ( attachParams . CustomPipeName ) && attachParams . CustomPipeName != "undefined" ;
355
+
356
+ PowerShellVersionDetails runspaceVersion =
357
+ _editorSession . PowerShellContext . CurrentRunspace . PowerShellVersion ;
358
+
353
359
// If there are no host processes to attach to or the user cancels selection, we get a null for the process id.
354
360
// This is not an error, just a request to stop the original "attach to" request.
355
361
// Testing against "undefined" is a HACK because I don't know how to make "Cancel" on quick pick loading
356
362
// to cancel on the VSCode side without sending an attachRequest with processId set to "undefined".
357
- if ( string . IsNullOrEmpty ( attachParams . ProcessId ) || ( attachParams . ProcessId == "undefined" ) )
363
+ if ( ! processIdIsSet && ! customPipeNameIsSet )
358
364
{
359
365
Logger . Write (
360
366
LogLevel . Normal ,
@@ -370,9 +376,6 @@ await requestContext.SendErrorAsync(
370
376
371
377
if ( attachParams . ComputerName != null )
372
378
{
373
- PowerShellVersionDetails runspaceVersion =
374
- _editorSession . PowerShellContext . CurrentRunspace . PowerShellVersion ;
375
-
376
379
if ( runspaceVersion . Version . Major < 4 )
377
380
{
378
381
await requestContext . SendErrorAsync (
@@ -403,16 +406,12 @@ await requestContext.SendErrorAsync(
403
406
_isRemoteAttach = true ;
404
407
}
405
408
406
- if ( int . TryParse ( attachParams . ProcessId , out int processId ) && ( processId > 0 ) )
409
+ if ( processIdIsSet && int . TryParse ( attachParams . ProcessId , out int processId ) && ( processId > 0 ) )
407
410
{
408
- PowerShellVersionDetails runspaceVersion =
409
- _editorSession . PowerShellContext . CurrentRunspace . PowerShellVersion ;
410
-
411
411
if ( runspaceVersion . Version . Major < 5 )
412
412
{
413
413
await requestContext . SendErrorAsync (
414
414
$ "Attaching to a process is only available with PowerShell 5 and higher (current session is { runspaceVersion . Version } ).") ;
415
-
416
415
return ;
417
416
}
418
417
@@ -427,20 +426,27 @@ await requestContext.SendErrorAsync(
427
426
428
427
return ;
429
428
}
429
+ }
430
+ else if ( customPipeNameIsSet )
431
+ {
432
+ if ( runspaceVersion . Version . Major < 6 && runspaceVersion . Version . Minor < 2 )
433
+ {
434
+ await requestContext . SendErrorAsync (
435
+ $ "Attaching to a process with CustomPipeName is only available with PowerShell 6.2 and higher (current session is { runspaceVersion . Version } ).") ;
436
+ return ;
437
+ }
438
+
439
+ await _editorSession . PowerShellContext . ExecuteScriptStringAsync (
440
+ $ "Enter-PSHostProcess -CustomPipeName { attachParams . CustomPipeName } ",
441
+ errorMessages ) ;
442
+
443
+ if ( errorMessages . Length > 0 )
444
+ {
445
+ await requestContext . SendErrorAsync (
446
+ $ "Could not attach to process with CustomPipeName: '{ attachParams . CustomPipeName } '") ;
430
447
431
- // Clear any existing breakpoints before proceeding
432
- await ClearSessionBreakpointsAsync ( ) ;
433
-
434
- // Execute the Debug-Runspace command but don't await it because it
435
- // will block the debug adapter initialization process. The
436
- // InitializedEvent will be sent as soon as the RunspaceChanged
437
- // event gets fired with the attached runspace.
438
- int runspaceId = attachParams . RunspaceId > 0 ? attachParams . RunspaceId : 1 ;
439
- _waitingForAttach = true ;
440
- Task nonAwaitedTask =
441
- _editorSession . PowerShellContext
442
- . ExecuteScriptStringAsync ( $ "\n Debug-Runspace -Id { runspaceId } ")
443
- . ContinueWith ( OnExecutionCompletedAsync ) ;
448
+ return ;
449
+ }
444
450
}
445
451
else
446
452
{
@@ -454,6 +460,20 @@ await requestContext.SendErrorAsync(
454
460
return ;
455
461
}
456
462
463
+ // Clear any existing breakpoints before proceeding
464
+ await ClearSessionBreakpointsAsync ( ) ;
465
+
466
+ // Execute the Debug-Runspace command but don't await it because it
467
+ // will block the debug adapter initialization process. The
468
+ // InitializedEvent will be sent as soon as the RunspaceChanged
469
+ // event gets fired with the attached runspace.
470
+ int runspaceId = attachParams . RunspaceId > 0 ? attachParams . RunspaceId : 1 ;
471
+ _waitingForAttach = true ;
472
+ Task nonAwaitedTask =
473
+ _editorSession . PowerShellContext
474
+ . ExecuteScriptStringAsync ( $ "\n Debug-Runspace -Id { runspaceId } ")
475
+ . ContinueWith ( OnExecutionCompletedAsync ) ;
476
+
457
477
await requestContext . SendResultAsync ( null ) ;
458
478
}
459
479
0 commit comments