diff --git a/src/vs/code/electron-main/app.ts b/src/vs/code/electron-main/app.ts index 33db58c922f98e78b931cea1945b354dd57a4f4c..597c45bad0240860afd4aea7e3c887d7b187fbe8 100644 --- a/src/vs/code/electron-main/app.ts +++ b/src/vs/code/electron-main/app.ts @@ -86,6 +86,7 @@ import { IKeyboardLayoutMainService, KeyboardLayoutMainService } from 'vs/platfo import { toErrorMessage } from 'vs/base/common/errorMessage'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import { DisplayMainService, IDisplayMainService } from 'vs/platform/display/electron-main/displayMainService'; +import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper'; export class CodeApplication extends Disposable { private windowsMainService: IWindowsMainService | undefined; @@ -703,7 +704,7 @@ export class CodeApplication extends Disposable { // Open our first window const args = this.environmentService.args; const macOpenFiles: string[] = (global).macOpenFiles; - const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP; + const context = isLaunchedFromCli(process.env) ? OpenContext.CLI : OpenContext.DESKTOP; const hasCliArgs = args._.length; const hasFolderURIs = !!args['folder-uri']; const hasFileURIs = !!args['file-uri']; diff --git a/src/vs/code/electron-main/window.ts b/src/vs/code/electron-main/window.ts index f8fe899ca4b4ef8e5020cb11087cc458ed234051..6019f2d2062dd9591408e4c6987a5916763c90c9 100644 --- a/src/vs/code/electron-main/window.ts +++ b/src/vs/code/electron-main/window.ts @@ -35,6 +35,7 @@ import { ILifecycleMainService } from 'vs/platform/lifecycle/electron-main/lifec import { IStorageMainService } from 'vs/platform/storage/node/storageMainService'; import { ByteSize, IFileService } from 'vs/platform/files/common/files'; import { FileAccess, Schemas } from 'vs/base/common/network'; +import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper'; export interface IWindowCreationOptions { state: IWindowState; @@ -677,6 +678,16 @@ export class CodeWindow extends Disposable implements ICodeWindow { load(config: INativeWindowConfiguration, isReload?: boolean, disableExtensions?: boolean): void { + // If this window was loaded before from the command line + // (as indicated by VSCODE_CLI environment), make sure to + // preserve that user environment in subsequent loads, + // unless the new configuration context was also a CLI + // (for https://github.com/microsoft/vscode/issues/108571) + const currentUserEnv = (this.currentConfig ?? this.pendingLoadConfig)?.userEnv; + if (currentUserEnv && isLaunchedFromCli(currentUserEnv) && !isLaunchedFromCli(config.userEnv)) { + config.userEnv = currentUserEnv; + } + // If this is the first time the window is loaded, we associate the paths // directly with the window because we assume the loading will just work if (this._readyState === ReadyState.NONE) { diff --git a/src/vs/code/node/shellEnv.ts b/src/vs/code/node/shellEnv.ts index a7422f5357a895b533ac5ea6e4f4f6786f859447..79ba3d252fe74dcfd5caa4ec77a50dded42b0465 100644 --- a/src/vs/code/node/shellEnv.ts +++ b/src/vs/code/node/shellEnv.ts @@ -8,6 +8,7 @@ import { generateUuid } from 'vs/base/common/uuid'; import { isWindows } from 'vs/base/common/platform'; import { ILogService } from 'vs/platform/log/common/log'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; +import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper'; /** * We need to get the environment from a user's shell. @@ -31,7 +32,7 @@ export async function resolveShellEnv(logService: ILogService, args: NativeParse } // Skip if running from CLI already - else if (env['VSCODE_CLI'] === '1' && !args['force-user-env']) { + else if (isLaunchedFromCli(env) && !args['force-user-env']) { logService.trace('resolveShellEnv(): skipped (VSCODE_CLI is set)'); return {}; @@ -39,7 +40,7 @@ export async function resolveShellEnv(logService: ILogService, args: NativeParse // Otherwise resolve (macOS, Linux) else { - if (env['VSCODE_CLI'] === '1') { + if (isLaunchedFromCli(env)) { logService.trace('resolveShellEnv(): running (--force-user-env)'); } else { logService.trace('resolveShellEnv(): running (macOS/Linux)'); diff --git a/src/vs/platform/environment/node/argvHelper.ts b/src/vs/platform/environment/node/argvHelper.ts index a3c16f98de7e888b407ee4560fafb6bcf6c98e11..3ace20cfc456455006f26b652e01a3883bcd5782 100644 --- a/src/vs/platform/environment/node/argvHelper.ts +++ b/src/vs/platform/environment/node/argvHelper.ts @@ -52,7 +52,7 @@ export function parseMainProcessArgv(processArgv: string[]): NativeParsedArgs { } // If called from CLI, don't report warnings as they are already reported. - let reportWarnings = !process.env['VSCODE_CLI']; + const reportWarnings = !isLaunchedFromCli(process.env); return parseAndValidate(args, reportWarnings); } @@ -60,7 +60,7 @@ export function parseMainProcessArgv(processArgv: string[]): NativeParsedArgs { * Use this to parse raw code CLI process.argv such as: `Electron cli.js . --verbose --wait` */ export function parseCLIProcessArgv(processArgv: string[]): NativeParsedArgs { - let [, , ...args] = processArgv; // remove the first non-option argument: it's always the app location + const [, , ...args] = processArgv; // remove the first non-option argument: it's always the app location return parseAndValidate(args, true); } @@ -78,3 +78,7 @@ export function addArg(argv: string[], ...args: string[]): string[] { return argv; } + +export function isLaunchedFromCli(env: NodeJS.ProcessEnv): boolean { + return env['VSCODE_CLI'] === '1'; +} diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 76e81a13ce7ac21e36d5e74e37f0cb3d631182e7..cef263622d4f8c7b757d35a1cd82effe7186dbd8 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -3,10 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import * as os from 'os'; import { IDebugParams, IExtensionHostDebugParams, INativeEnvironmentService } from 'vs/platform/environment/common/environment'; import { NativeParsedArgs } from 'vs/platform/environment/common/argv'; import * as paths from 'vs/base/node/paths'; -import * as os from 'os'; import * as path from 'vs/base/common/path'; import * as resources from 'vs/base/common/resources'; import { memoize } from 'vs/base/common/decorators'; diff --git a/src/vs/platform/launch/electron-main/launchMainService.ts b/src/vs/platform/launch/electron-main/launchMainService.ts index ac0c66cf60013917292e8329e8792e558bfa4907..069bb585c19ed5d52e0965d4d5b7a43daa0efaf6 100644 --- a/src/vs/platform/launch/electron-main/launchMainService.ts +++ b/src/vs/platform/launch/electron-main/launchMainService.ts @@ -19,6 +19,7 @@ import { BrowserWindow, ipcMain, Event as IpcEvent, app } from 'electron'; import { coalesce } from 'vs/base/common/arrays'; import { IDiagnosticInfoOptions, IDiagnosticInfo, IRemoteDiagnosticInfo, IRemoteDiagnosticError } from 'vs/platform/diagnostics/common/diagnostics'; import { IMainProcessInfo, IWindowInfo } from 'vs/platform/launch/node/launch'; +import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper'; export const ID = 'launchMainService'; export const ILaunchMainService = createDecorator(ID); @@ -112,7 +113,7 @@ export class LaunchMainService implements ILaunchMainService { } private startOpenWindow(args: NativeParsedArgs, userEnv: IProcessEnvironment): Promise { - const context = !!userEnv['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP; + const context = isLaunchedFromCli(userEnv) ? OpenContext.CLI : OpenContext.DESKTOP; let usedWindows: ICodeWindow[] = []; const waitMarkerFileURI = args.wait && args.waitMarkerFilePath ? URI.file(args.waitMarkerFilePath) : undefined;