@@ -87,15 +87,14 @@ export const DebugConfigurations: Record<DebugConfig, DebugConfiguration> = {
87
87
name : "PowerShell: Attach to PowerShell Host Process" ,
88
88
type : "PowerShell" ,
89
89
request : "attach" ,
90
- runspaceId : 1 ,
91
90
} ,
92
91
[ DebugConfig . RunPester ] : {
93
92
name : "PowerShell: Run Pester Tests" ,
94
93
type : "PowerShell" ,
95
94
request : "launch" ,
96
95
script : "Invoke-Pester" ,
97
96
createTemporaryIntegratedConsole : true ,
98
- attachDotnetDebugger : true
97
+ attachDotnetDebugger : true ,
99
98
} ,
100
99
[ DebugConfig . ModuleInteractiveSession ] : {
101
100
name : "PowerShell: Module Interactive Session" ,
@@ -109,15 +108,15 @@ export const DebugConfigurations: Record<DebugConfig, DebugConfiguration> = {
109
108
request : "launch" ,
110
109
script : "Enter command to import your binary module, for example: \"Import-Module -Force ${workspaceFolder}/path/to/module.psd1|dll\"" ,
111
110
createTemporaryIntegratedConsole : true ,
112
- attachDotnetDebugger : true
111
+ attachDotnetDebugger : true ,
113
112
} ,
114
113
[ DebugConfig . BinaryModulePester ] : {
115
114
name : "PowerShell: Binary Module Pester Tests" ,
116
115
type : "PowerShell" ,
117
116
request : "launch" ,
118
117
script : "Invoke-Pester" ,
119
118
createTemporaryIntegratedConsole : true ,
120
- attachDotnetDebugger : true
119
+ attachDotnetDebugger : true ,
121
120
}
122
121
} ;
123
122
@@ -131,7 +130,7 @@ export class DebugSessionFeature extends LanguageClientConsumer
131
130
132
131
constructor ( context : ExtensionContext , private sessionManager : SessionManager , private logger : ILogger ) {
133
132
super ( ) ;
134
- // This "activates" the debug adapter for use with You can only do this once.
133
+ // This "activates" the debug adapter. You can only do this once.
135
134
[
136
135
DebugConfigurationProviderTriggerKind . Initial ,
137
136
DebugConfigurationProviderTriggerKind . Dynamic
@@ -276,11 +275,15 @@ export class DebugSessionFeature extends LanguageClientConsumer
276
275
return resolvedConfig ;
277
276
}
278
277
279
- // This is our factory entrypoint hook to when a debug session starts, and where we will lazy initialize everything needed to do the debugging such as a temporary console if required
278
+ // This is our factory entrypoint hook to when a debug session starts, and
279
+ // where we will lazy initialize everything needed to do the debugging such
280
+ // as a temporary console if required.
281
+ //
282
+ // NOTE: A Promise meets the shape of a ProviderResult, which allows us to
283
+ // make this method async.
280
284
public async createDebugAdapterDescriptor (
281
285
session : DebugSession ,
282
286
_executable : DebugAdapterExecutable | undefined ) : Promise < DebugAdapterDescriptor | undefined > {
283
- // NOTE: A Promise meets the shape of a ProviderResult, which allows us to make this method async.
284
287
285
288
await this . sessionManager . start ( ) ;
286
289
@@ -426,6 +429,7 @@ export class DebugSessionFeature extends LanguageClientConsumer
426
429
this . logger . writeVerbose ( `Dotnet attach debug configuration: ${ JSON . stringify ( dotnetAttachConfig , undefined , 2 ) } ` ) ;
427
430
this . logger . writeVerbose ( `Attached dotnet debugger to process: ${ pid } ` ) ;
428
431
}
432
+
429
433
return this . tempSessionDetails ;
430
434
}
431
435
@@ -452,7 +456,7 @@ export class DebugSessionFeature extends LanguageClientConsumer
452
456
} ;
453
457
}
454
458
455
- /** Fetches all available vscode launch configurations. This is abstracted out for easier testing */
459
+ /** Fetches all available vscode launch configurations. This is abstracted out for easier testing. */
456
460
private getLaunchConfigurations ( ) : DebugConfiguration [ ] {
457
461
return workspace . getConfiguration ( "launch" ) . get < DebugConfiguration [ ] > ( "configurations" ) ?? [ ] ;
458
462
}
@@ -480,6 +484,23 @@ export class DebugSessionFeature extends LanguageClientConsumer
480
484
}
481
485
}
482
486
487
+ // If we were given a stringified int from the user, or from the picker
488
+ // command, we need to parse it here.
489
+ if ( typeof config . processId === "string" && config . processId != "current" ) {
490
+ config . processId = parseInt ( config . processId ) ;
491
+ }
492
+
493
+ // NOTE: We don't support attaching to the Extension Terminal, even
494
+ // though in the past it looked like we did. The implementation was
495
+ // half-baked and left things unusable.
496
+ if ( config . processId === "current" || config . processId === await this . sessionManager . getLanguageServerPid ( ) ) {
497
+ // TODO: When (if ever) it's supported, we need to convert 0 and the
498
+ // old notion of "current" to the actual process ID, like this:
499
+ // config.processId = await this.sessionManager.getLanguageServerPid();
500
+ void this . logger . writeAndShowError ( "Attaching to the PowerShell Extension terminal is not supported. Please use the 'PowerShell: Interactive Session' debug configuration instead." ) ;
501
+ return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG ;
502
+ }
503
+
483
504
if ( ! config . runspaceId && ! config . runspaceName ) {
484
505
config . runspaceId = await commands . executeCommand ( "PowerShell.PickRunspace" , config . processId ) ;
485
506
// No runspace selected. Cancel attach.
@@ -528,12 +549,13 @@ export class SpecifyScriptArgsFeature implements Disposable {
528
549
if ( text !== undefined ) {
529
550
await this . context . workspaceState . update ( powerShellDbgScriptArgsKey , text ) ;
530
551
}
552
+
531
553
return text ;
532
554
}
533
555
}
534
556
535
557
interface IProcessItem extends QuickPickItem {
536
- pid : string ; // payload for the QuickPick UI
558
+ processId : number ; // payload for the QuickPick UI
537
559
}
538
560
539
561
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -542,7 +564,7 @@ interface IGetPSHostProcessesArguments {
542
564
543
565
interface IPSHostProcessInfo {
544
566
processName : string ;
545
- processId : string ;
567
+ processId : number ;
546
568
appDomainName : string ;
547
569
mainWindowTitle : string ;
548
570
}
@@ -551,19 +573,16 @@ export const GetPSHostProcessesRequestType =
551
573
new RequestType < IGetPSHostProcessesArguments , IPSHostProcessInfo [ ] , string > ( "powerShell/getPSHostProcesses" ) ;
552
574
553
575
export class PickPSHostProcessFeature extends LanguageClientConsumer {
554
-
555
576
private command : Disposable ;
556
577
private waitingForClientToken ?: CancellationTokenSource ;
557
578
private getLanguageClientResolve ?: ( value : LanguageClient ) => void ;
558
579
559
580
constructor ( private logger : ILogger ) {
560
581
super ( ) ;
561
582
562
- this . command =
563
- commands . registerCommand ( "PowerShell.PickPSHostProcess" , ( ) => {
564
- return this . getLanguageClient ( )
565
- . then ( ( _ ) => this . pickPSHostProcess ( ) , ( _ ) => undefined ) ;
566
- } ) ;
583
+ this . command = commands . registerCommand ( "PowerShell.PickPSHostProcess" , async ( ) => {
584
+ return this . pickPSHostProcess ( ) ;
585
+ } ) ;
567
586
}
568
587
569
588
public override setLanguageClient ( languageClient : LanguageClient ) : void {
@@ -617,25 +636,24 @@ export class PickPSHostProcessFeature extends LanguageClientConsumer {
617
636
}
618
637
}
619
638
620
- private async pickPSHostProcess ( ) : Promise < string | undefined > {
639
+ private async pickPSHostProcess ( ) : Promise < number | undefined > {
640
+ // We need the language client in order to send the request.
641
+ await this . getLanguageClient ( ) ;
642
+
621
643
// Start with the current PowerShell process in the list.
622
- const items : IProcessItem [ ] = [ {
623
- label : "Current" ,
624
- description : "The current PowerShell Extension process." ,
625
- pid : "current" ,
626
- } ] ;
644
+ const items : IProcessItem [ ] = [ ] ;
627
645
628
646
const response = await this . languageClient ?. sendRequest ( GetPSHostProcessesRequestType , { } ) ;
629
647
for ( const process of response ?? [ ] ) {
630
648
let windowTitle = "" ;
631
649
if ( process . mainWindowTitle ) {
632
- windowTitle = `, Title: ${ process . mainWindowTitle } ` ;
650
+ windowTitle = `, ${ process . mainWindowTitle } ` ;
633
651
}
634
652
635
653
items . push ( {
636
654
label : process . processName ,
637
655
description : `PID: ${ process . processId . toString ( ) } ${ windowTitle } ` ,
638
- pid : process . processId ,
656
+ processId : process . processId ,
639
657
} ) ;
640
658
}
641
659
@@ -648,9 +666,10 @@ export class PickPSHostProcessFeature extends LanguageClientConsumer {
648
666
matchOnDescription : true ,
649
667
matchOnDetail : true ,
650
668
} ;
669
+
651
670
const item = await window . showQuickPick ( items , options ) ;
652
671
653
- return item ? item . pid : undefined ;
672
+ return item ?. processId ?? undefined ;
654
673
}
655
674
656
675
private clearWaitingToken ( ) : void {
@@ -660,7 +679,7 @@ export class PickPSHostProcessFeature extends LanguageClientConsumer {
660
679
}
661
680
662
681
interface IRunspaceItem extends QuickPickItem {
663
- id : string ; // payload for the QuickPick UI
682
+ id : number ; // payload for the QuickPick UI
664
683
}
665
684
666
685
// eslint-disable-next-line @typescript-eslint/no-empty-interface
@@ -677,18 +696,16 @@ export const GetRunspaceRequestType =
677
696
new RequestType < IGetRunspaceRequestArguments , IRunspace [ ] , string > ( "powerShell/getRunspace" ) ;
678
697
679
698
export class PickRunspaceFeature extends LanguageClientConsumer {
680
-
681
699
private command : Disposable ;
682
700
private waitingForClientToken ?: CancellationTokenSource ;
683
701
private getLanguageClientResolve ?: ( value : LanguageClient ) => void ;
684
702
685
703
constructor ( private logger : ILogger ) {
686
704
super ( ) ;
687
- this . command =
688
- commands . registerCommand ( "PowerShell.PickRunspace" , ( processId ) => {
689
- return this . getLanguageClient ( )
690
- . then ( ( _ ) => this . pickRunspace ( processId ) , ( _ ) => undefined ) ;
691
- } , this ) ;
705
+
706
+ this . command = commands . registerCommand ( "PowerShell.PickRunspace" ,
707
+ async ( processId ) => { return this . pickRunspace ( processId ) ; } ,
708
+ this ) ;
692
709
}
693
710
694
711
public override setLanguageClient ( languageClient : LanguageClient ) : void {
@@ -734,28 +751,26 @@ export class PickRunspaceFeature extends LanguageClientConsumer {
734
751
this . clearWaitingToken ( ) ;
735
752
reject ( ) ;
736
753
737
- void this . logger . writeAndShowError ( "Attach to PowerShell host process: PowerShell session took too long to start." ) ;
754
+ void this . logger . writeAndShowError (
755
+ "Attach to PowerShell host process: PowerShell session took too long to start." ) ;
738
756
}
739
757
} , 60000 ) ;
740
758
} ,
741
759
) ;
742
760
}
743
761
}
744
762
745
- private async pickRunspace ( processId : string ) : Promise < string | undefined > {
763
+ private async pickRunspace ( processId : number ) : Promise < number | undefined > {
764
+ // We need the language client in order to send the request.
765
+ await this . getLanguageClient ( ) ;
766
+
746
767
const response = await this . languageClient ?. sendRequest ( GetRunspaceRequestType , { processId } ) ;
747
768
const items : IRunspaceItem [ ] = [ ] ;
748
769
for ( const runspace of response ?? [ ] ) {
749
- // Skip default runspace
750
- if ( ( runspace . id === 1 || runspace . name === "PSAttachRunspace" )
751
- && processId === "current" ) {
752
- continue ;
753
- }
754
-
755
770
items . push ( {
756
771
label : runspace . name ,
757
772
description : `ID: ${ runspace . id } - ${ runspace . availability } ` ,
758
- id : runspace . id . toString ( ) ,
773
+ id : runspace . id ,
759
774
} ) ;
760
775
}
761
776
@@ -764,9 +779,10 @@ export class PickRunspaceFeature extends LanguageClientConsumer {
764
779
matchOnDescription : true ,
765
780
matchOnDetail : true ,
766
781
} ;
782
+
767
783
const item = await window . showQuickPick ( items , options ) ;
768
784
769
- return item ? item . id : undefined ;
785
+ return item ? .id ?? undefined ;
770
786
}
771
787
772
788
private clearWaitingToken ( ) : void {
0 commit comments