Skip to content

Commit 82be83b

Browse files
committed
Enhance additionalPowerShellExes setting
Now the warning that's emitted when an additional PowerShell executable isn't found can be suppressed with a setting. If the setting's value has single or double quotes, it handles it. If the executable name wasn't appended, it handles it. Smarter!
1 parent d24725c commit 82be83b

File tree

3 files changed

+50
-7
lines changed

3 files changed

+50
-7
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -669,6 +669,11 @@
669669
"markdownDescription": "**Deprecated:** Specifies whether you should be prompted to update your version of `PackageManagement` if it's under 1.4.6.",
670670
"markdownDeprecationMessage": "**Deprecated:** This prompt has been removed as it's no longer strictly necessary to upgrade the `PackageManagement` module."
671671
},
672+
"powershell.suppressAdditionalExeNotFoundWarning": {
673+
"type": "boolean",
674+
"default": false,
675+
"markdownDescription": "Suppresses the warning message when any of `#powershell.powerShellAdditionalExePaths#` is not found."
676+
},
672677
"powershell.startAsLoginShell.osx": {
673678
"type": "boolean",
674679
"default": true,

src/platform.ts

Lines changed: 44 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import * as os from "os";
55
import * as path from "path";
66
import * as process from "process";
7+
import vscode = require("vscode");
78
import { integer } from "vscode-languageserver-protocol";
89
import { ILogger } from "./logging";
9-
import { PowerShellAdditionalExePathSettings } from "./settings";
10+
import { changeSetting, getSettings, PowerShellAdditionalExePathSettings } from "./settings";
1011

1112
// This uses require so we can rewire it in unit tests!
1213
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-var-requires
@@ -149,8 +150,12 @@ export class PowerShellExeFinder {
149150
for (const additionalPwsh of this.enumerateAdditionalPowerShellInstallations()) {
150151
if (await additionalPwsh.exists()) {
151152
yield additionalPwsh;
152-
} else {
153-
void this.logger.writeAndShowWarning(`Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`);
153+
} else if (!additionalPwsh.suppressWarning
154+
&& !getSettings().suppressAdditionalExeNotFoundWarning) {
155+
const selection = await vscode.window.showWarningMessage(`Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`, "Don't Show Again");
156+
if (selection !== undefined) {
157+
await changeSetting("suppressAdditionalExeNotFoundWarning", true, true, this.logger);
158+
}
154159
}
155160
}
156161
}
@@ -223,9 +228,39 @@ export class PowerShellExeFinder {
223228
private *enumerateAdditionalPowerShellInstallations(): Iterable<IPossiblePowerShellExe> {
224229
for (const versionName in this.additionalPowerShellExes) {
225230
if (Object.prototype.hasOwnProperty.call(this.additionalPowerShellExes, versionName)) {
226-
const exePath = this.additionalPowerShellExes[versionName];
227-
if (exePath) {
228-
yield new PossiblePowerShellExe(exePath, versionName);
231+
let exePath = this.additionalPowerShellExes[versionName];
232+
if (!exePath) {
233+
continue;
234+
}
235+
236+
// Remove surrounding quotes from path (without regex)
237+
if (exePath.startsWith("'") && exePath.endsWith("'")
238+
|| exePath.startsWith("\"") && exePath.endsWith("\"")) {
239+
exePath = exePath.slice(1, -1);
240+
}
241+
242+
// Always search for what the user gave us first
243+
yield new PossiblePowerShellExe(exePath, versionName);
244+
245+
// Also search for `pwsh[.exe]` and `powershell[.exe]` if missing
246+
const args: [string, undefined, boolean, boolean]
247+
// Must be a tuple type and is suppressing the warning
248+
= [versionName, undefined, true, true];
249+
250+
// Handle Windows where '.exe' and 'powershell' are things
251+
if (this.platformDetails.operatingSystem === OperatingSystem.Windows) {
252+
if (!exePath.endsWith("pwsh.exe") && !exePath.endsWith("powershell.exe")) {
253+
if (exePath.endsWith("pwsh") || exePath.endsWith("powershell")) {
254+
// Add extension if that was missing
255+
yield new PossiblePowerShellExe(exePath + ".exe", ...args);
256+
}
257+
// Also add full exe names (this isn't an else just in case
258+
// the folder was named "pwsh" or "powershell")
259+
yield new PossiblePowerShellExe(path.join(exePath, "pwsh.exe"), ...args);
260+
yield new PossiblePowerShellExe(path.join(exePath, "powershell.exe"), ...args);
261+
}
262+
} else if (!exePath.endsWith("pwsh")) { // Always just 'pwsh' on non-Windows
263+
yield new PossiblePowerShellExe(path.join(exePath, "pwsh"), ...args);
229264
}
230265
}
231266
}
@@ -529,14 +564,16 @@ export function getWindowsSystemPowerShellPath(systemFolderName: string): string
529564

530565
interface IPossiblePowerShellExe extends IPowerShellExeDetails {
531566
exists(): Promise<boolean>;
567+
readonly suppressWarning: boolean;
532568
}
533569

534570
class PossiblePowerShellExe implements IPossiblePowerShellExe {
535571
constructor(
536572
public readonly exePath: string,
537573
public readonly displayName: string,
538574
private knownToExist?: boolean,
539-
public readonly supportsProperArguments = true) { }
575+
public readonly supportsProperArguments = true,
576+
public readonly suppressWarning = false) { }
540577

541578
public async exists(): Promise<boolean> {
542579
if (this.knownToExist === undefined) {

src/settings.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export class Settings extends PartialSettings {
2323
// This setting is no longer used but is here to assist in cleaning up the users settings.
2424
powerShellExePath = "";
2525
promptToUpdatePowerShell = true;
26+
suppressAdditionalExeNotFoundWarning = false;
2627
startAsLoginShell = new StartAsLoginShellSettings();
2728
startAutomatically = true;
2829
enableProfileLoading = true;

0 commit comments

Comments
 (0)