4
4
5
5
import vscode = require( 'vscode' ) ;
6
6
import { IFeature } from '../feature' ;
7
- import { LanguageClient } from 'vscode-languageclient' ;
7
+ import { LanguageClient , RequestType , NotificationType } from 'vscode-languageclient' ;
8
8
9
9
export class DebugSessionFeature implements IFeature {
10
10
private command : vscode . Disposable ;
@@ -40,4 +40,117 @@ export class DebugSessionFeature implements IFeature {
40
40
41
41
vscode . commands . executeCommand ( 'vscode.startDebug' , config ) ;
42
42
}
43
- }
43
+ }
44
+
45
+ interface ProcessItem extends vscode . QuickPickItem {
46
+ pid : string ; // payload for the QuickPick UI
47
+ }
48
+
49
+ interface PSHostProcessInfo {
50
+ processName : string ;
51
+ processId : string ;
52
+ appDomainName : string ;
53
+ mainWindowTitle : string ;
54
+ }
55
+
56
+ namespace GetPSHostProcessesRequest {
57
+ export const type : RequestType < any , GetPSHostProcessesResponseBody , string > =
58
+ { get method ( ) { return 'powerShell/getPSHostProcesses' ; } } ;
59
+ }
60
+
61
+ interface GetPSHostProcessesResponseBody {
62
+ hostProcesses : PSHostProcessInfo [ ] ;
63
+ }
64
+
65
+ export class PickPSHostProcessFeature implements IFeature {
66
+
67
+ private command : vscode . Disposable ;
68
+ private languageClient : LanguageClient ;
69
+ private waitingForClientToken : vscode . CancellationTokenSource ;
70
+
71
+ constructor ( ) {
72
+ this . command =
73
+ vscode . commands . registerCommand ( 'PowerShell.PickPSHostProcess' , ( ) => {
74
+
75
+ if ( ! this . languageClient && ! this . waitingForClientToken ) {
76
+
77
+ // If PowerShell isn't finished loading yet, show a loading message
78
+ // until the LanguageClient is passed on to us
79
+ this . waitingForClientToken = new vscode . CancellationTokenSource ( ) ;
80
+ vscode . window
81
+ . showQuickPick (
82
+ [ "Cancel" ] ,
83
+ { placeHolder : "Select PowerShell Host Process to attach to: Please wait, starting PowerShell..." } ,
84
+ this . waitingForClientToken . token )
85
+ . then ( response => { if ( response === "Cancel" ) { this . clearWaitingToken ( ) ; } } ) ;
86
+
87
+ // Cancel the loading prompt after 60 seconds
88
+ setTimeout ( ( ) => {
89
+ if ( this . waitingForClientToken ) {
90
+ this . clearWaitingToken ( ) ;
91
+
92
+ vscode . window . showErrorMessage (
93
+ "Select PowerShell Host Process to attach to: PowerShell session took too long to start." ) ;
94
+ }
95
+ } , 60000 ) ;
96
+ }
97
+ else {
98
+ return this . pickPSHostProcess ( ) ;
99
+ }
100
+ } ) ;
101
+ }
102
+
103
+ public setLanguageClient ( languageClient : LanguageClient ) {
104
+ this . languageClient = languageClient ;
105
+
106
+ if ( this . waitingForClientToken ) {
107
+ this . clearWaitingToken ( ) ;
108
+ return this . pickPSHostProcess ( ) ;
109
+ }
110
+ }
111
+
112
+ public dispose ( ) {
113
+ this . command . dispose ( ) ;
114
+ }
115
+
116
+ // In node, the function returned a Promise<string> not sure about "Thenable<string>"
117
+ private pickPSHostProcess ( ) : Thenable < string > {
118
+ return this . languageClient . sendRequest ( GetPSHostProcessesRequest . type , null ) . then ( hostProcesses => {
119
+ var items : ProcessItem [ ] = [ ] ;
120
+
121
+ for ( var p in hostProcesses ) {
122
+ items . push ( {
123
+ label : hostProcesses [ p ] . processName ,
124
+ description : hostProcesses [ p ] . processId . toString ( ) ,
125
+ detail : hostProcesses [ p ] . mainWindowTitle ,
126
+ pid : hostProcesses [ p ] . processId
127
+ } ) ;
128
+ } ;
129
+
130
+ if ( items . length === 0 ) {
131
+ return vscode . window . showInformationMessage (
132
+ "There are no other PowerShell host processes to attach to." ) . then ( _ => {
133
+ return null ;
134
+ } ) ;
135
+ }
136
+ else {
137
+ let options : vscode . QuickPickOptions = {
138
+ placeHolder : "Select a PowerShell Host process to attach to" ,
139
+ matchOnDescription : true ,
140
+ matchOnDetail : true
141
+ } ;
142
+
143
+ return vscode . window . showQuickPick ( items , options ) . then ( item => {
144
+ return item ? item . pid : null ;
145
+ } ) ;
146
+ }
147
+ } ) ;
148
+ }
149
+
150
+ private clearWaitingToken ( ) {
151
+ if ( this . waitingForClientToken ) {
152
+ this . waitingForClientToken . dispose ( ) ;
153
+ this . waitingForClientToken = undefined ;
154
+ }
155
+ }
156
+ }
0 commit comments