未验证 提交 513c68ac 编写于 作者: T Tyler James Leonhardt 提交者: GitHub

fix powershell 7 64bit not showing in 32bit vscode on 64bit Windows (#116986)

* powershell 7 not showing in 32bit vscode on 64bit Windows
Fixes #116032

* make enum const
上级 78707e2d
...@@ -8,18 +8,72 @@ import * as os from 'os'; ...@@ -8,18 +8,72 @@ import * as os from 'os';
import * as path from 'vs/base/common/path'; import * as path from 'vs/base/common/path';
import { env } from 'vs/base/common/process'; import { env } from 'vs/base/common/process';
const WindowsPowerShell64BitLabel = 'Windows PowerShell';
const WindowsPowerShell32BitLabel = 'Windows PowerShell (x86)';
// This is required, since parseInt("7-preview") will return 7. // This is required, since parseInt("7-preview") will return 7.
const IntRegex: RegExp = /^\d+$/; const IntRegex: RegExp = /^\d+$/;
const PwshMsixRegex: RegExp = /^Microsoft.PowerShell_.*/; const PwshMsixRegex: RegExp = /^Microsoft.PowerShell_.*/;
const PwshPreviewMsixRegex: RegExp = /^Microsoft.PowerShellPreview_.*/; const PwshPreviewMsixRegex: RegExp = /^Microsoft.PowerShellPreview_.*/;
// The platform details descriptor for the platform we're on const enum Arch {
const isProcess64Bit: boolean = process.arch === 'x64'; x64,
const isOS64Bit: boolean = isProcess64Bit || os.arch() === 'x64'; x86,
ARM
}
let processArch: Arch;
switch (process.arch) {
case 'ia32':
case 'x32':
processArch = Arch.x86;
break;
case 'arm':
case 'arm64':
processArch = Arch.ARM;
break;
default:
processArch = Arch.x64;
break;
}
/*
Currently, here are the values for these environment variables on their respective archs:
On x86 process on x86:
PROCESSOR_ARCHITECTURE is X86
PROCESSOR_ARCHITEW6432 is undefined
On x86 process on x64:
PROCESSOR_ARCHITECTURE is X86
PROCESSOR_ARCHITEW6432 is AMD64
On x64 process on x64:
PROCESSOR_ARCHITECTURE is AMD64
PROCESSOR_ARCHITEW6432 is undefined
On ARM process on ARM:
PROCESSOR_ARCHITECTURE is ARM64
PROCESSOR_ARCHITEW6432 is undefined
On x86 process on ARM:
PROCESSOR_ARCHITECTURE is X86
PROCESSOR_ARCHITEW6432 is ARM64
On x64 process on ARM:
PROCESSOR_ARCHITECTURE is ARM64
PROCESSOR_ARCHITEW6432 is undefined
*/
let osArch: Arch;
if (process.env['PROCESSOR_ARCHITEW6432']) {
osArch = process.env['PROCESSOR_ARCHITEW6432'] === 'ARM64'
? Arch.ARM
: Arch.x64;
} else if (process.env['PROCESSOR_ARCHITECTURE'] === 'ARM64') {
osArch = Arch.ARM;
} else if (process.env['PROCESSOR_ARCHITECTURE'] === 'X86') {
osArch = Arch.x86;
} else {
osArch = Arch.x64;
}
export interface IPowerShellExeDetails { export interface IPowerShellExeDetails {
readonly displayName: string; readonly displayName: string;
...@@ -53,12 +107,12 @@ function getProgramFilesPath( ...@@ -53,12 +107,12 @@ function getProgramFilesPath(
} }
// We might be a 64-bit process looking for 32-bit program files // We might be a 64-bit process looking for 32-bit program files
if (isProcess64Bit) { if (processArch === Arch.x64) {
return env['ProgramFiles(x86)'] || null; return env['ProgramFiles(x86)'] || null;
} }
// We might be a 32-bit process looking for 64-bit program files // We might be a 32-bit process looking for 64-bit program files
if (isOS64Bit) { if (osArch === Arch.x64) {
return env.ProgramW6432 || null; return env.ProgramW6432 || null;
} }
...@@ -66,28 +120,6 @@ function getProgramFilesPath( ...@@ -66,28 +120,6 @@ function getProgramFilesPath(
return null; return null;
} }
function getSystem32Path({ useAlternateBitness = false }: { useAlternateBitness?: boolean } = {}): string {
const windir: string = env.windir!;
if (!useAlternateBitness) {
// Just use the native system bitness
return path.join(windir, 'System32');
}
// We might be a 64-bit process looking for 32-bit system32
if (isProcess64Bit) {
return path.join(windir, 'SysWOW64');
}
// We might be a 32-bit process looking for 64-bit system32
if (isOS64Bit) {
return path.join(windir, 'Sysnative');
}
// We're on a 32-bit Windows, so no alternate bitness
return path.join(windir, 'System32');
}
async function findPSCoreWindowsInstallation( async function findPSCoreWindowsInstallation(
{ useAlternateBitness = false, findPreview = false }: { useAlternateBitness = false, findPreview = false }:
{ useAlternateBitness?: boolean; findPreview?: boolean } = {}): Promise<IPossiblePowerShellExe | null> { { useAlternateBitness?: boolean; findPreview?: boolean } = {}): Promise<IPossiblePowerShellExe | null> {
...@@ -196,33 +228,13 @@ function findPSCoreDotnetGlobalTool(): IPossiblePowerShellExe { ...@@ -196,33 +228,13 @@ function findPSCoreDotnetGlobalTool(): IPossiblePowerShellExe {
return new PossiblePowerShellExe(dotnetGlobalToolExePath, '.NET Core PowerShell Global Tool'); return new PossiblePowerShellExe(dotnetGlobalToolExePath, '.NET Core PowerShell Global Tool');
} }
function findWinPS({ useAlternateBitness = false }: { useAlternateBitness?: boolean } = {}): IPossiblePowerShellExe | null { function findWinPS(): IPossiblePowerShellExe | null {
const winPSPath = path.join(
env.windir!,
processArch === Arch.x86 && osArch !== Arch.x86 ? 'SysNative' : 'System32',
'WindowsPowerShell', 'v1.0', 'powershell.exe');
// x86 and ARM only have one WinPS on them return new PossiblePowerShellExe(winPSPath, 'Windows PowerShell', true);
if (!isOS64Bit && useAlternateBitness) {
return null;
}
const systemFolderPath = getSystem32Path({ useAlternateBitness });
const winPSPath = path.join(systemFolderPath, 'WindowsPowerShell', 'v1.0', 'powershell.exe');
let displayName: string;
if (isProcess64Bit) {
displayName = useAlternateBitness
? WindowsPowerShell32BitLabel
: WindowsPowerShell64BitLabel;
} else if (isOS64Bit) {
displayName = useAlternateBitness
? WindowsPowerShell64BitLabel
: WindowsPowerShell32BitLabel;
} else {
// NOTE: ARM Windows devices also have Windows PowerShell x86 on them. There is no
// "ARM Windows PowerShell".
displayName = WindowsPowerShell32BitLabel;
}
return new PossiblePowerShellExe(winPSPath, displayName, true);
} }
/** /**
...@@ -276,18 +288,10 @@ async function* enumerateDefaultPowerShellInstallations(): AsyncIterable<IPossib ...@@ -276,18 +288,10 @@ async function* enumerateDefaultPowerShellInstallations(): AsyncIterable<IPossib
} }
// Finally, get Windows PowerShell // Finally, get Windows PowerShell
// Get the natural Windows PowerShell for the process bitness
pwshExe = findWinPS(); pwshExe = findWinPS();
if (pwshExe) { if (pwshExe) {
yield pwshExe; yield pwshExe;
} }
// Get the alternate bitness Windows PowerShell
pwshExe = findWinPS({ useAlternateBitness: true });
if (pwshExe) {
yield pwshExe;
}
} }
/** /**
......
...@@ -4,7 +4,6 @@ ...@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/ *--------------------------------------------------------------------------------------------*/
import * as assert from 'assert'; import * as assert from 'assert';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os';
import * as platform from 'vs/base/common/platform'; import * as platform from 'vs/base/common/platform';
import { enumeratePowerShellInstallations, getFirstAvailablePowerShellInstallation, IPowerShellExeDetails } from 'vs/base/node/powershell'; import { enumeratePowerShellInstallations, getFirstAvailablePowerShellInstallation, IPowerShellExeDetails } from 'vs/base/node/powershell';
...@@ -40,44 +39,20 @@ if (platform.isWindows) { ...@@ -40,44 +39,20 @@ if (platform.isWindows) {
}); });
test('Can enumerate PowerShells', async () => { test('Can enumerate PowerShells', async () => {
const isOS64Bit = os.arch() === 'x64';
const pwshs = new Array<IPowerShellExeDetails>(); const pwshs = new Array<IPowerShellExeDetails>();
for await (const p of enumeratePowerShellInstallations()) { for await (const p of enumeratePowerShellInstallations()) {
pwshs.push(p); pwshs.push(p);
} }
const powershellLog = 'Found these PowerShells:\n' + pwshs.map(p => `${p.displayName}: ${p.exePath}`).join('\n'); const powershellLog = 'Found these PowerShells:\n' + pwshs.map(p => `${p.displayName}: ${p.exePath}`).join('\n');
assert.strictEqual(pwshs.length >= (isOS64Bit ? 2 : 1), true, powershellLog); assert.strictEqual(pwshs.length >= 1, true, powershellLog);
for (const pwsh of pwshs) { for (const pwsh of pwshs) {
checkPath(pwsh.exePath); checkPath(pwsh.exePath);
} }
// The last one should always be Windows PowerShell.
const lastIndex = pwshs.length - 1; assert.strictEqual(pwshs[pwshs.length - 1].displayName, 'Windows PowerShell', powershellLog);
const secondToLastIndex = pwshs.length - 2;
// 64bit process on 64bit OS
if (process.arch === 'x64') {
checkPath(pwshs[secondToLastIndex].exePath);
assert.strictEqual(pwshs[secondToLastIndex].displayName, 'Windows PowerShell', powershellLog);
checkPath(pwshs[lastIndex].exePath);
assert.strictEqual(pwshs[lastIndex].displayName, 'Windows PowerShell (x86)', powershellLog);
} else if (isOS64Bit) {
// 32bit process on 64bit OS
// Windows PowerShell x86 comes first if vscode is 32bit
checkPath(pwshs[secondToLastIndex].exePath);
assert.strictEqual(pwshs[secondToLastIndex].displayName, 'Windows PowerShell (x86)', powershellLog);
checkPath(pwshs[lastIndex].exePath);
assert.strictEqual(pwshs[lastIndex].displayName, 'Windows PowerShell', powershellLog);
} else {
// 32bit or ARM process
checkPath(pwshs[lastIndex].exePath);
assert.strictEqual(pwshs[lastIndex].displayName, 'Windows PowerShell (x86)', powershellLog);
}
}); });
}); });
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册