Skip to content

Feature: Add sessionName debug setting to allow different PS for temp console #5208

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@
}
},
{
"label": "Run Pester Tests (Binary Module)",
"label": "PowerShell: Run Pester Tests (Binary Module)",
"description": "Debug a .NET binary or hybrid module by running Pester tests. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
"body": {
"name": "PowerShell: Binary Module Pester Tests",
Expand All @@ -529,6 +529,16 @@
"createTemporaryIntegratedConsole": true,
"attachDotnetDebugger": true
}
},
{
"label": "PowerShell: Windows PowerShell",
"description": "(Windows Only) Launch a temporary Windows PowerShell console for debugging. This is useful for debugging legacy scripts that require Windows PowerShell.",
"body": {
"name": "PowerShell: Windows PowerShell",
"type": "PowerShell",
"request": "launch",
"sessionName": "Windows PowerShell (x64)"
}
}
],
"configurationAttributes": {
Expand Down Expand Up @@ -556,6 +566,14 @@
"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'.",
"default": false
},
"sessionName": {
"type": [
"string",
"null"
],
"description": "If specified, uses the PowerShell session name to launch the debug configuration. Will always launch in a temporary console if specified.",
"default": null
},
"attachDotnetDebugger": {
"type": "boolean",
"description": "If specified, a C# debug session will be started and attached to the new temporary extension terminal. This does nothing unless 'powershell.debugging.createTemporaryIntegratedConsole' is also specified.",
Expand Down
29 changes: 27 additions & 2 deletions src/features/DebugSession.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ export enum DebugConfig {
ModuleInteractiveSession,
BinaryModule,
BinaryModulePester,
WindowsPowerShell,
}

/** Make the implicit behavior of undefined and null in the debug api more explicit */
Expand Down Expand Up @@ -126,6 +127,12 @@ export const DebugConfigurations: Record<DebugConfig, DebugConfiguration> = {
createTemporaryIntegratedConsole: true,
attachDotnetDebugger: true,
},
[DebugConfig.WindowsPowerShell]: {
name: "PowerShell: Windows PowerShell",
type: "PowerShell",
request: "launch",
sessionName: "Windows PowerShell (x64)",
},
};

export class DebugSessionFeature
Expand Down Expand Up @@ -271,13 +278,24 @@ export class DebugSessionFeature
"Debug a .NET binary or hybrid module loaded into a PowerShell session. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
},
{
id: DebugConfig.RunPester,
id: DebugConfig.BinaryModulePester,
label: "Run Pester Tests (Binary Module)",
description:
"Debug a .NET binary or hybrid module by running Pester tests. Breakpoints you set in your .NET (C#/F#/VB/etc.) code will be hit upon command execution. You may want to add a compile or watch action as a pre-launch task to this configuration.",
},
];

// Only show the Windows PowerShell option if the platform is Windows
const platformDetails = getPlatformDetails();
if (platformDetails.operatingSystem === OperatingSystem.Windows) {
debugConfigPickItems.push({
id: DebugConfig.WindowsPowerShell,
label: "Windows PowerShell",
description:
"Launch Windows PowerShell in a temporary integrated console for debugging",
});
}

const launchSelection = await window.showQuickPick(
debugConfigPickItems,
{ placeHolder: "Select a PowerShell debug configuration" },
Expand Down Expand Up @@ -440,6 +458,10 @@ export class DebugSessionFeature
return PREVENT_DEBUG_START_AND_OPEN_DEBUGCONFIG;
}

if (config.sessionName) {
config.createTemporaryIntegratedConsole = true;
}

if (config.attachDotnetDebugger) {
return this.resolveAttachDotnetDebugConfiguration(config);
}
Expand Down Expand Up @@ -477,7 +499,10 @@ export class DebugSessionFeature
): Promise<IEditorServicesSessionDetails | undefined> {
const settings = getSettings();
this.tempDebugProcess =
await this.sessionManager.createDebugSessionProcess(settings);
await this.sessionManager.createDebugSessionProcess(
settings,
session.configuration.sessionName,
);
// TODO: Maybe set a timeout on the cancellation token?
const cancellationTokenSource = new CancellationTokenSource();
this.tempSessionDetails = await this.tempDebugProcess.start(
Expand Down
15 changes: 12 additions & 3 deletions src/session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ export class SessionManager implements Middleware {

public async createDebugSessionProcess(
settings: Settings,
powershellExeName?: string,
): Promise<PowerShellProcess> {
// NOTE: We only support one temporary Extension Terminal at a time. To
// support more, we need to track each separately, and tie the session
Expand All @@ -455,14 +456,20 @@ export class SessionManager implements Middleware {
);
}

const debugPowerShellExeDetails =
powershellExeName === undefined
? this.PowerShellExeDetails
: ((await this.findPowerShell(powershellExeName)) ??
this.PowerShellExeDetails);

// TODO: It might not be totally necessary to update the session
// settings here, but I don't want to accidentally change this behavior
// just yet. Working on getting things to be more idempotent!
this.sessionSettings = settings;

const bundledModulesPath = await this.getBundledModulesPath();
this.debugSessionProcess = new PowerShellProcess(
this.PowerShellExeDetails.exePath,
debugPowerShellExeDetails.exePath,
bundledModulesPath,
true,
false,
Expand Down Expand Up @@ -716,7 +723,9 @@ export class SessionManager implements Middleware {
];
}

private async findPowerShell(): Promise<IPowerShellExeDetails | undefined> {
private async findPowerShell(
wantedName?: string,
): Promise<IPowerShellExeDetails | undefined> {
this.logger.writeDebug("Finding PowerShell...");
const powershellExeFinder = new PowerShellExeFinder(
this.platformDetails,
Expand All @@ -727,7 +736,7 @@ export class SessionManager implements Middleware {
let foundPowerShell: IPowerShellExeDetails | undefined;
try {
let defaultPowerShell: IPowerShellExeDetails | undefined;
const wantedName = this.sessionSettings.powerShellDefaultVersion;
wantedName ??= this.sessionSettings.powerShellDefaultVersion;
if (wantedName !== "") {
for await (const details of powershellExeFinder.enumeratePowerShellInstallations()) {
// Need to compare names case-insensitively, from https://stackoverflow.com/a/2140723
Expand Down
Loading