Skip to content

Commit 2399e15

Browse files
authored
Merge pull request PowerShell#435 from rkeithhill/rkeihthill/pshost-process-picker
Provide quick pick list of processes when using debugger attach configuration
2 parents 1ce8b35 + 92f00b8 commit 2399e15

File tree

3 files changed

+128
-8
lines changed

3 files changed

+128
-8
lines changed

package.json

+10-5
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@
2929
"onLanguage:powershell",
3030
"onCommand:PowerShell.NewProjectFromTemplate",
3131
"onCommand:PowerShell.OpenExamplesFolder",
32-
"onCommand:PowerShell.StartDebugSession"
32+
"onCommand:PowerShell.StartDebugSession",
33+
"onCommand:PowerShell.PickPSHostProcess"
3334
],
3435
"dependencies": {
3536
"vscode-languageclient": "1.3.1"
@@ -164,6 +165,9 @@
164165
},
165166
"program": "./out/debugAdapter.js",
166167
"runtime": "node",
168+
"variables": {
169+
"PickPSHostProcess": "PowerShell.PickPSHostProcess"
170+
},
167171
"languages": ["powershell"],
168172
"startSessionCommand": "PowerShell.StartDebugSession",
169173
"configurationSnippets": [
@@ -198,8 +202,8 @@
198202
"type": "PowerShell",
199203
"request": "attach",
200204
"name": "PowerShell Attach to Process",
201-
"processId": "${ProcessId}",
202-
"runspaceId": "1"
205+
"processId": "^\"\\${command.PickPSHostProcess}\"",
206+
"runspaceId": 1
203207
}
204208
},
205209
{
@@ -246,8 +250,9 @@
246250
"description": "Optional: The computer name to which a remote session will be established. Works only on PowerShell 4 and above."
247251
},
248252
"processId": {
249-
"type": "number",
250-
"description": "The ID of the process to be attached. Works only on PowerShell 5 and above."
253+
"type": "string",
254+
"description": "Id of PowerShell host process to attach to. Works only on PowerShell 5 and above.",
255+
"default": "${command.PickPSHostProcess}"
251256
},
252257
"runspaceId": {
253258
"type": "number",

src/features/DebugSession.ts

+115-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import vscode = require('vscode');
66
import { IFeature } from '../feature';
7-
import { LanguageClient } from 'vscode-languageclient';
7+
import { LanguageClient, RequestType, NotificationType } from 'vscode-languageclient';
88

99
export 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+
}

src/main.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import { ExpandAliasFeature } from './features/ExpandAlias';
1717
import { ShowHelpFeature } from './features/ShowOnlineHelp';
1818
import { CodeActionsFeature } from './features/CodeActions';
1919
import { DebugSessionFeature } from './features/DebugSession';
20+
import { PickPSHostProcessFeature } from './features/DebugSession';
2021
import { SelectPSSARulesFeature } from './features/SelectPSSARules';
2122
import { FindModuleFeature } from './features/PowerShellFindModule';
2223
import { NewFileOrProjectFeature } from './features/NewFileOrProject';
@@ -103,7 +104,8 @@ export function activate(context: vscode.ExtensionContext): void {
103104
new SelectPSSARulesFeature(),
104105
new CodeActionsFeature(),
105106
new NewFileOrProjectFeature(),
106-
new DebugSessionFeature()
107+
new DebugSessionFeature(),
108+
new PickPSHostProcessFeature()
107109
];
108110

109111
sessionManager =

0 commit comments

Comments
 (0)