Skip to content

Commit 613f208

Browse files
committed
Add attachDotnetDebugger debug option
1 parent ecc1b2a commit 613f208

File tree

3 files changed

+151
-6
lines changed

3 files changed

+151
-6
lines changed

package.json

+5
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,11 @@
522522
"type": "boolean",
523523
"description": "Determines whether a temporary PowerShell Extension Terminal is created for each debugging session, useful for debugging PowerShell classes and binary modules. Overrides the user setting 'powershell.debugging.createTemporaryIntegratedConsole'.",
524524
"default": false
525+
},
526+
"attachDotnetDebugger": {
527+
"type": "boolean",
528+
"description": "If specified, a C# debug session will be started and attach to the new temporary PSIC. This does nothing unless createTemporaryIntegratedConsole is also specified.",
529+
"default": false
525530
}
526531
}
527532
},

src/features/DebugSession.ts

+140-5
Original file line numberDiff line numberDiff line change
@@ -283,14 +283,149 @@ export class DebugSessionFeature extends LanguageClientConsumer
283283
}
284284
}
285285

286-
if (!config.runspaceId && !config.runspaceName) {
287-
config.runspaceId = await vscode.commands.executeCommand("PowerShell.PickRunspace", config.processId);
288-
// No runspace selected. Cancel attach.
289-
if (!config.runspaceId) {
290-
return null;
286+
if (!config.runspaceId && !config.runspaceName) {
287+
config.runspaceId = await vscode.commands.executeCommand("PowerShell.PickRunspace", config.processId);
288+
289+
// No runspace selected. Cancel attach.
290+
if (!config.runspaceId) {
291+
return null;
292+
}
291293
}
292294
}
293295

296+
// TODO: Use a named debug configuration.
297+
if (generateLaunchConfig) {
298+
// No launch.json, create the default configuration for both unsaved (Untitled) and saved documents.
299+
config.type = "PowerShell";
300+
config.name = "PowerShell: Launch Current File";
301+
config.request = "launch";
302+
config.args = [];
303+
304+
config.script =
305+
currentDocument.isUntitled
306+
? currentDocument.uri.toString()
307+
: currentDocument.fileName;
308+
309+
if (config.createTemporaryIntegratedConsole) {
310+
// For a folder-less workspace, vscode.workspace.rootPath will be undefined.
311+
// PSES will convert that undefined to a reasonable working dir.
312+
config.cwd =
313+
currentDocument.isUntitled
314+
? vscode.workspace.rootPath
315+
: currentDocument.fileName;
316+
317+
} else {
318+
// If the non-temp integrated console is being used, default to the current working dir.
319+
config.cwd = "";
320+
}
321+
}
322+
323+
if (config.request === "launch") {
324+
// For debug launch of "current script" (saved or unsaved), warn before starting the debugger if either
325+
// A) there is not an active document
326+
// B) the unsaved document's language type is not PowerShell
327+
// C) the saved document's extension is a type that PowerShell can't debug.
328+
if (debugCurrentScript) {
329+
330+
if (currentDocument === undefined) {
331+
const msg = "To debug the \"Current File\", you must first open a " +
332+
"PowerShell script file in the editor.";
333+
vscode.window.showErrorMessage(msg);
334+
return;
335+
}
336+
337+
if (currentDocument.isUntitled) {
338+
if (config.createTemporaryIntegratedConsole) {
339+
const msg = "Debugging Untitled files in a temporary console is currently not supported.";
340+
vscode.window.showErrorMessage(msg);
341+
return;
342+
}
343+
344+
if (currentDocument.languageId === "powershell") {
345+
if (!generateLaunchConfig) {
346+
// Cover the case of existing launch.json but unsaved (Untitled) document.
347+
// In this case, vscode.workspace.rootPath will not be undefined.
348+
config.script = currentDocument.uri.toString();
349+
config.cwd = vscode.workspace.rootPath;
350+
}
351+
} else {
352+
const msg = "To debug '" + currentDocument.fileName + "', change the document's " +
353+
"language mode to PowerShell or save the file with a PowerShell extension.";
354+
vscode.window.showErrorMessage(msg);
355+
return;
356+
}
357+
} else {
358+
let isValidExtension = false;
359+
const extIndex = currentDocument.fileName.lastIndexOf(".");
360+
if (extIndex !== -1) {
361+
const ext = currentDocument.fileName.substr(extIndex + 1).toUpperCase();
362+
isValidExtension = (ext === "PS1" || ext === "PSM1");
363+
}
364+
365+
if ((currentDocument.languageId !== "powershell") || !isValidExtension) {
366+
let docPath = currentDocument.fileName;
367+
const workspaceRootPath = vscode.workspace.rootPath;
368+
if (currentDocument.fileName.startsWith(workspaceRootPath)) {
369+
docPath = currentDocument.fileName.substring(vscode.workspace.rootPath.length + 1);
370+
}
371+
372+
const msg = "PowerShell does not support debugging this file type: '" + docPath + "'.";
373+
vscode.window.showErrorMessage(msg);
374+
return;
375+
}
376+
377+
if (config.script === "${file}") {
378+
config.script = currentDocument.fileName;
379+
}
380+
}
381+
}
382+
383+
// NOTE: There is a tight coupling to a weird setting in
384+
// `package.json` for the Launch Current File configuration where
385+
// the default cwd is set to ${file}.
386+
if ((currentDocument !== undefined) && (config.cwd === "${file}")) {
387+
config.cwd = currentDocument.fileName;
388+
}
389+
}
390+
391+
// Prevent the Debug Console from opening
392+
config.internalConsoleOptions = "neverOpen";
393+
394+
// Create or show the interactive console
395+
vscode.commands.executeCommand("PowerShell.ShowSessionConsole", true);
396+
397+
const sessionFilePath = utils.getDebugSessionFilePath();
398+
399+
if (config.createTemporaryIntegratedConsole) {
400+
if (this.tempDebugProcess) {
401+
this.tempDebugProcess.dispose();
402+
}
403+
404+
this.tempDebugProcess =
405+
this.sessionManager.createDebugSessionProcess(
406+
sessionFilePath,
407+
settings);
408+
409+
this.tempSessionDetails = await this.tempDebugProcess.start(`DebugSession-${this.sessionCount++}`);
410+
utils.writeSessionFile(sessionFilePath, this.tempSessionDetails);
411+
412+
if (config.attachDotnetDebugger) {
413+
// Will wait until the process is started and available before attaching
414+
const pid = await this.tempDebugProcess.getPid();
415+
416+
await vscode.debug.startDebugging(undefined, {
417+
name: "Dotnet Debugger: PSIC Temporary Console",
418+
type: "coreclr",
419+
request: "attach",
420+
processId: pid
421+
});
422+
this.logger.write(`Attached dotnet debugger to process ${pid}`)
423+
}
424+
425+
} else {
426+
utils.writeSessionFile(sessionFilePath, this.sessionManager.getSessionDetails());
427+
}
428+
294429
return config;
295430
}
296431
}

src/process.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,13 @@ export class PowerShellProcess {
134134
return sessionDetails;
135135
}
136136

137+
// Returns the process Id of the consoleTerminal
138+
public async getPid() {
139+
return await this.consoleTerminal.processId
140+
}
141+
137142
public showTerminal(preserveFocus?: boolean) {
138-
this.consoleTerminal?.show(preserveFocus);
143+
this.consoleTerminal?.show(preserveFocus)
139144
}
140145

141146
public async dispose() {

0 commit comments

Comments
 (0)