44
55import vscode = require( 'vscode' ) ;
66import { IFeature } from '../feature' ;
7- import { LanguageClient } from 'vscode-languageclient' ;
7+ import { LanguageClient , RequestType , NotificationType } from 'vscode-languageclient' ;
88
99export class DebugSessionFeature implements IFeature {
1010 private command : vscode . Disposable ;
@@ -40,4 +40,117 @@ export class DebugSessionFeature implements IFeature {
4040
4141 vscode . commands . executeCommand ( 'vscode.startDebug' , config ) ;
4242 }
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