diff --git a/src/platform.ts b/src/platform.ts index 76ca5992ed..87802f8f4b 100644 --- a/src/platform.ts +++ b/src/platform.ts @@ -42,6 +42,7 @@ export interface IPlatformDetails { operatingSystem: OperatingSystem; isOS64Bit: boolean; isProcess64Bit: boolean; + isArm64: boolean; } export interface IPowerShellExeDetails { @@ -68,6 +69,7 @@ export function getPlatformDetails(): IPlatformDetails { isOS64Bit: isProcess64Bit || process.env.PROCESSOR_ARCHITEW6432 !== undefined, isProcess64Bit, + isArm64: process.arch === "arm64", }; } @@ -562,93 +564,96 @@ export class PowerShellExeFinder { }: { useAlternateBitness?: boolean; findPreview?: boolean } = {}): Promise< IPossiblePowerShellExe | undefined > { - const programFilesPath = this.getProgramFilesPath({ + for (const programFilesPath of this.getProgramFilesPath({ useAlternateBitness, - }); + })) { - if (!programFilesPath) { - return undefined; - } + if (!programFilesPath) { + continue; + } - const powerShellInstallBaseDir = path.join( - programFilesPath, - "PowerShell", - ); + const powerShellInstallBaseDir = path.join( + programFilesPath, + "PowerShell", + ); - // Ensure the base directory exists - if (!(await utils.checkIfDirectoryExists(powerShellInstallBaseDir))) { - return undefined; - } + // Ensure the base directory exists + if (!(await utils.checkIfDirectoryExists(powerShellInstallBaseDir))) { + continue; + } - let highestSeenVersion = -1; - let pwshExePath: string | undefined; - for (const item of await utils.readDirectory( - powerShellInstallBaseDir, - )) { - let currentVersion = -1; - if (findPreview) { - // We are looking for something like "7-preview" - - // Preview dirs all have dashes in them - const dashIndex: integer = item.indexOf("-"); - if (dashIndex < 0) { - continue; - } + let highestSeenVersion = -1; + let pwshExePath: string | undefined; + for (const item of await utils.readDirectory( + powerShellInstallBaseDir, + )) { + let currentVersion = -1; + if (findPreview) { + // We are looking for something like "7-preview" + + // Preview dirs all have dashes in them + const dashIndex: integer = item.indexOf("-"); + if (dashIndex < 0) { + continue; + } - // Verify that the part before the dash is an integer - const intPart: string = item.substring(0, dashIndex); - if (!PowerShellExeFinder.IntRegex.test(intPart)) { - continue; + // Verify that the part before the dash is an integer + const intPart: string = item.substring(0, dashIndex); + if (!PowerShellExeFinder.IntRegex.test(intPart)) { + continue; + } + + // Verify that the part after the dash is "preview" + if (item.substring(dashIndex + 1) !== "preview") { + continue; + } + + currentVersion = parseInt(intPart, 10); + } else { + // Search for a directory like "6" or "7" + if (!PowerShellExeFinder.IntRegex.test(item)) { + continue; + } + + currentVersion = parseInt(item, 10); } - // Verify that the part after the dash is "preview" - if (item.substring(dashIndex + 1) !== "preview") { + // Ensure we haven't already seen a higher version + if (currentVersion <= highestSeenVersion) { continue; } - currentVersion = parseInt(intPart, 10); - } else { - // Search for a directory like "6" or "7" - if (!PowerShellExeFinder.IntRegex.test(item)) { + // Now look for the file + const exePath = path.join( + powerShellInstallBaseDir, + item, + "pwsh.exe", + ); + if (!(await utils.checkIfFileExists(exePath))) { continue; } - currentVersion = parseInt(item, 10); + pwshExePath = exePath; + highestSeenVersion = currentVersion; } - // Ensure we haven't already seen a higher version - if (currentVersion <= highestSeenVersion) { + if (!pwshExePath) { continue; } - // Now look for the file - const exePath = path.join( - powerShellInstallBaseDir, - item, - "pwsh.exe", - ); - if (!(await utils.checkIfFileExists(exePath))) { - continue; - } + const bitness: string = programFilesPath.includes("x86") + ? "(x86)" + : "(x64)"; - pwshExePath = exePath; - highestSeenVersion = currentVersion; - } + const preview: string = findPreview ? " Preview" : ""; - if (!pwshExePath) { - return undefined; + return new PossiblePowerShellExe( + pwshExePath, + `PowerShell${preview} ${bitness}`, + ); } - const bitness: string = programFilesPath.includes("x86") - ? "(x86)" - : "(x64)"; - - const preview: string = findPreview ? " Preview" : ""; - - return new PossiblePowerShellExe( - pwshExePath, - `PowerShell${preview} ${bitness}`, - ); + return undefined; } private findWinPS({ @@ -707,24 +712,29 @@ export class PowerShellExeFinder { private getProgramFilesPath({ useAlternateBitness = false, - }: { useAlternateBitness?: boolean } = {}): string | undefined { + }: { useAlternateBitness?: boolean } = {}): (string | undefined)[] { + const result: (string | undefined)[] = []; + if (!useAlternateBitness) { // Just use the native system bitness - return process.env.ProgramFiles; - } + result.push(process.env.ProgramFiles); - // We might be a 64-bit process looking for 32-bit program files - if (this.platformDetails.isProcess64Bit) { - return process.env["ProgramFiles(x86)"]; - } + // We might be a Arm64 process looking for Arm program files + if (this.platformDetails.isArm64) { + result.push(process.env["ProgramFiles(Arm)"]); + } + } else { + // We might be a 64-bit process looking for 32-bit program files + if (this.platformDetails.isProcess64Bit) { + result.push(process.env["ProgramFiles(x86)"]); + } - // We might be a 32-bit process looking for 64-bit program files - if (this.platformDetails.isOS64Bit) { - return process.env.ProgramW6432; + // We might be a 32-bit process looking for 64-bit program files + if (this.platformDetails.isOS64Bit) { + result.push(process.env.ProgramW6432); + } } - - // We're a 32-bit process on 32-bit Windows, there is no other Program Files dir - return undefined; + return result; } private getSystem32Path({ diff --git a/test/core/platform.test.ts b/test/core/platform.test.ts index e6de6a5f3a..ee0d0d83d4 100644 --- a/test/core/platform.test.ts +++ b/test/core/platform.test.ts @@ -60,20 +60,22 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: { ProgramFiles: "C:\\Program Files", "ProgramFiles(x86)": "C:\\Program Files (x86)", + "ProgramFiles(Arm)": "C:\\Program Files (Arm)", windir: "C:\\WINDOWS", }, expectedPowerShellSequence: [ { - exePath: "C:\\Program Files\\PowerShell\\6\\pwsh.exe", + exePath: "C:\\Program Files\\PowerShell\\7\\pwsh.exe", displayName: "PowerShell (x64)", supportsProperArguments: true, }, { - exePath: "C:\\Program Files (x86)\\PowerShell\\6\\pwsh.exe", + exePath: "C:\\Program Files (x86)\\PowerShell\\7\\pwsh.exe", displayName: "PowerShell (x86)", supportsProperArguments: true, }, @@ -114,7 +116,108 @@ if (process.platform === "win32") { ], filesystem: { "C:\\Program Files\\PowerShell": { - "6": { + "7": { + "pwsh.exe": "", + }, + "7-preview": { + "pwsh.exe": "", + }, + }, + "C:\\Program Files (Arm)\\PowerShell": { + "7": { + "pwsh.exe": "", + }, + "7-preview": { + "pwsh.exe": "", + }, + }, + "C:\\Program Files (x86)\\PowerShell": { + "7": { + "pwsh.exe": "", + }, + "7-preview": { + "pwsh.exe": "", + }, + }, + [msixAppDir]: { + "Microsoft.PowerShell_8wekyb3d8bbwe": { + "pwsh.exe": "", + }, + "Microsoft.PowerShellPreview_8wekyb3d8bbwe": { + "pwsh.exe": "", + }, + }, + "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0": { + "powershell.exe": "", + }, + "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0": { + "powershell.exe": "", + }, + }, + }, + { + name: "Windows 64-bit, 64-bit VSCode (no x86-64)", + platformDetails: { + operatingSystem: platform.OperatingSystem.Windows, + isOS64Bit: true, + isProcess64Bit: true, + isArm64: true, + }, + environmentVars: { + ProgramFiles: "C:\\Program Files", + "ProgramFiles(x86)": "C:\\Program Files (x86)", + "ProgramFiles(Arm)": "C:\\Program Files (Arm)", + windir: "C:\\WINDOWS", + }, + expectedPowerShellSequence: [ + { + exePath: "C:\\Program Files (Arm)\\PowerShell\\7\\pwsh.exe", + displayName: "PowerShell (x64)", + supportsProperArguments: true, + }, + { + exePath: "C:\\Program Files (x86)\\PowerShell\\7\\pwsh.exe", + displayName: "PowerShell (x86)", + supportsProperArguments: true, + }, + { + exePath: pwshMsixPath, + displayName: "PowerShell (Store)", + supportsProperArguments: true, + }, + { + exePath: + "C:\\Program Files (Arm)\\PowerShell\\7-preview\\pwsh.exe", + displayName: "PowerShell Preview (x64)", + supportsProperArguments: true, + }, + { + exePath: pwshPreviewMsixPath, + displayName: "PowerShell Preview (Store)", + supportsProperArguments: true, + }, + { + exePath: + "C:\\Program Files (x86)\\PowerShell\\7-preview\\pwsh.exe", + displayName: "PowerShell Preview (x86)", + supportsProperArguments: true, + }, + { + exePath: + "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", + displayName: "Windows PowerShell (x64)", + supportsProperArguments: true, + }, + { + exePath: + "C:\\WINDOWS\\SysWOW64\\WindowsPowerShell\\v1.0\\powershell.exe", + displayName: "Windows PowerShell (x86)", + supportsProperArguments: true, + }, + ], + filesystem: { + "C:\\Program Files (Arm)\\PowerShell": { + "7": { "pwsh.exe": "", }, "7-preview": { @@ -122,7 +225,7 @@ if (process.platform === "win32") { }, }, "C:\\Program Files (x86)\\PowerShell": { - "6": { + "7": { "pwsh.exe": "", }, "7-preview": { @@ -151,10 +254,12 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: { ProgramFiles: "C:\\Program Files", "ProgramFiles(x86)": "C:\\Program Files (x86)", + "ProgramFiles(Arm)": "C:\\Program Files (Arm)", windir: "C:\\WINDOWS", }, expectedPowerShellSequence: [ @@ -186,6 +291,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: true, isProcess64Bit: false, + isArm64: false, }, environmentVars: { ProgramFiles: "C:\\Program Files (x86)", @@ -194,12 +300,12 @@ if (process.platform === "win32") { }, expectedPowerShellSequence: [ { - exePath: "C:\\Program Files (x86)\\PowerShell\\6\\pwsh.exe", + exePath: "C:\\Program Files (x86)\\PowerShell\\7\\pwsh.exe", displayName: "PowerShell (x86)", supportsProperArguments: true, }, { - exePath: "C:\\Program Files\\PowerShell\\6\\pwsh.exe", + exePath: "C:\\Program Files\\PowerShell\\7\\pwsh.exe", displayName: "PowerShell (x64)", supportsProperArguments: true, }, @@ -240,7 +346,7 @@ if (process.platform === "win32") { ], filesystem: { "C:\\Program Files\\PowerShell": { - "6": { + "7": { "pwsh.exe": "", }, "7-preview": { @@ -248,7 +354,7 @@ if (process.platform === "win32") { }, }, "C:\\Program Files (x86)\\PowerShell": { - "6": { + "7": { "pwsh.exe": "", }, "7-preview": { @@ -277,6 +383,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: true, isProcess64Bit: false, + isArm64: false, }, environmentVars: { ProgramFiles: "C:\\Program Files (x86)", @@ -312,6 +419,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: false, isProcess64Bit: false, + isArm64: false, }, environmentVars: { ProgramFiles: "C:\\Program Files (x86)", @@ -320,7 +428,7 @@ if (process.platform === "win32") { }, expectedPowerShellSequence: [ { - exePath: "C:\\Program Files (x86)\\PowerShell\\6\\pwsh.exe", + exePath: "C:\\Program Files (x86)\\PowerShell\\7\\pwsh.exe", displayName: "PowerShell (x86)", supportsProperArguments: true, }, @@ -349,7 +457,7 @@ if (process.platform === "win32") { ], filesystem: { "C:\\Program Files (x86)\\PowerShell": { - "6": { + "7": { "pwsh.exe": "", }, "7-preview": { @@ -375,6 +483,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: false, isProcess64Bit: false, + isArm64: false, }, environmentVars: { ProgramFiles: "C:\\Program Files (x86)", @@ -401,6 +510,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: true, isProcess64Bit: true, + isArm64: false, }, environmentVars: { USERNAME: "test", @@ -453,6 +563,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Windows, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: { USERNAME: "test", @@ -513,6 +624,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Linux, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, expectedPowerShellSequence: [ @@ -554,6 +666,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.MacOS, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, expectedPowerShellSequence: [ @@ -601,6 +714,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Linux, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, expectedPowerShellSequence: [ @@ -622,6 +736,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Linux, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, expectedPowerShellSequence: [ @@ -643,6 +758,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.MacOS, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, expectedPowerShellSequence: [ @@ -664,6 +780,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.MacOS, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: { USER: "test", @@ -688,6 +805,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Linux, isOS64Bit: true, isProcess64Bit: true, + isArm64: false, }, environmentVars: { USER: "test", @@ -724,6 +842,7 @@ if (process.platform === "win32") { operatingSystem: platform.OperatingSystem.Linux, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: { USER: "test", @@ -781,6 +900,7 @@ const errorTestCases: ITestPlatform[] = [ operatingSystem: platform.OperatingSystem.Linux, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, filesystem: {}, @@ -791,6 +911,7 @@ const errorTestCases: ITestPlatform[] = [ operatingSystem: platform.OperatingSystem.MacOS, isOS64Bit: true, isProcess64Bit: true, + isArm64: true, }, environmentVars: {}, filesystem: {},