|
4 | 4 | import * as os from "os";
|
5 | 5 | import * as path from "path";
|
6 | 6 | import * as process from "process";
|
| 7 | +import vscode = require("vscode"); |
7 | 8 | import { integer } from "vscode-languageserver-protocol";
|
8 | 9 | import { ILogger } from "./logging";
|
9 |
| -import { PowerShellAdditionalExePathSettings } from "./settings"; |
| 10 | +import { changeSetting, getSettings, PowerShellAdditionalExePathSettings } from "./settings"; |
10 | 11 |
|
11 | 12 | // This uses require so we can rewire it in unit tests!
|
12 | 13 | // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-var-requires
|
@@ -41,6 +42,7 @@ export interface IPowerShellExeDetails {
|
41 | 42 | readonly displayName: string;
|
42 | 43 | readonly exePath: string;
|
43 | 44 | readonly supportsProperArguments: boolean;
|
| 45 | + readonly suppressWarning: boolean; |
44 | 46 | }
|
45 | 47 |
|
46 | 48 | export function getPlatformDetails(): IPlatformDetails {
|
@@ -149,8 +151,12 @@ export class PowerShellExeFinder {
|
149 | 151 | for (const additionalPwsh of this.enumerateAdditionalPowerShellInstallations()) {
|
150 | 152 | if (await additionalPwsh.exists()) {
|
151 | 153 | yield additionalPwsh;
|
152 |
| - } else { |
153 |
| - void this.logger.writeAndShowWarning(`Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`); |
| 154 | + } else if (!additionalPwsh.suppressWarning |
| 155 | + && !getSettings().suppressAdditionalExeNotFoundWarning) { |
| 156 | + const selection = await vscode.window.showWarningMessage(`Additional PowerShell '${additionalPwsh.displayName}' not found at '${additionalPwsh.exePath}'!`, "Don't Show Again"); |
| 157 | + if (selection !== undefined) { |
| 158 | + await changeSetting("suppressAdditionalExeNotFoundWarning", true, true, this.logger); |
| 159 | + } |
154 | 160 | }
|
155 | 161 | }
|
156 | 162 | }
|
@@ -223,9 +229,39 @@ export class PowerShellExeFinder {
|
223 | 229 | private *enumerateAdditionalPowerShellInstallations(): Iterable<IPossiblePowerShellExe> {
|
224 | 230 | for (const versionName in this.additionalPowerShellExes) {
|
225 | 231 | if (Object.prototype.hasOwnProperty.call(this.additionalPowerShellExes, versionName)) {
|
226 |
| - const exePath = this.additionalPowerShellExes[versionName]; |
227 |
| - if (exePath) { |
228 |
| - yield new PossiblePowerShellExe(exePath, versionName); |
| 232 | + let exePath = this.additionalPowerShellExes[versionName]; |
| 233 | + if (!exePath) { |
| 234 | + continue; |
| 235 | + } |
| 236 | + |
| 237 | + // Remove surrounding quotes from path (without regex) |
| 238 | + if (exePath.startsWith("'") && exePath.endsWith("'") |
| 239 | + || exePath.startsWith("\"") && exePath.endsWith("\"")) { |
| 240 | + exePath = exePath.slice(1, -1); |
| 241 | + } |
| 242 | + |
| 243 | + // Always search for what the user gave us first |
| 244 | + yield new PossiblePowerShellExe(exePath, versionName); |
| 245 | + |
| 246 | + // Also search for `pwsh[.exe]` and `powershell[.exe]` if missing |
| 247 | + const args: [string, undefined, boolean, boolean] |
| 248 | + // Must be a tuple type and is suppressing the warning |
| 249 | + = [versionName, undefined, true, true]; |
| 250 | + |
| 251 | + // Handle Windows where '.exe' and 'powershell' are things |
| 252 | + if (this.platformDetails.operatingSystem === OperatingSystem.Windows) { |
| 253 | + if (!exePath.endsWith("pwsh.exe") && !exePath.endsWith("powershell.exe")) { |
| 254 | + if (exePath.endsWith("pwsh") || exePath.endsWith("powershell")) { |
| 255 | + // Add extension if that was missing |
| 256 | + yield new PossiblePowerShellExe(exePath + ".exe", ...args); |
| 257 | + } |
| 258 | + // Also add full exe names (this isn't an else just in case |
| 259 | + // the folder was named "pwsh" or "powershell") |
| 260 | + yield new PossiblePowerShellExe(exePath + "\\pwsh.exe", ...args); |
| 261 | + yield new PossiblePowerShellExe(exePath + "\\powershell.exe", ...args); |
| 262 | + } |
| 263 | + } else if (!exePath.endsWith("pwsh")) { // Always just 'pwsh' on non-Windows |
| 264 | + yield new PossiblePowerShellExe(exePath + "/pwsh", ...args); |
229 | 265 | }
|
230 | 266 | }
|
231 | 267 | }
|
@@ -536,7 +572,8 @@ class PossiblePowerShellExe implements IPossiblePowerShellExe {
|
536 | 572 | public readonly exePath: string,
|
537 | 573 | public readonly displayName: string,
|
538 | 574 | private knownToExist?: boolean,
|
539 |
| - public readonly supportsProperArguments = true) { } |
| 575 | + public readonly supportsProperArguments = true, |
| 576 | + public readonly suppressWarning = false) { } |
540 | 577 |
|
541 | 578 | public async exists(): Promise<boolean> {
|
542 | 579 | if (this.knownToExist === undefined) {
|
|
0 commit comments