diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index f346bc765b4d76b305d4d59cfb3207a599709915..8e26c2218ff4bd3e13e954c5b2c0ed4faba691d4 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -17,6 +17,7 @@ import { WindowsChannel } from 'vs/platform/windows/common/windowsIpc'; import { WindowsService } from 'vs/platform/windows/electron-main/windowsService'; import { LifecycleService, ILifecycleService } from 'vs/code/electron-main/lifecycle'; import { VSCodeMenu } from 'vs/code/electron-main/menus'; +import { getShellEnvironment } from 'vs/code/electron-main/shellEnv'; import { IUpdateService } from 'vs/platform/update/common/update'; import { UpdateChannel } from 'vs/platform/update/common/updateIpc'; import { UpdateService } from 'vs/platform/update/electron-main/updateService'; @@ -44,7 +45,6 @@ import { IConfigurationService } from 'vs/platform/configuration/common/configur import { ConfigurationService } from 'vs/platform/configuration/node/configurationService'; import { IRequestService } from 'vs/platform/request/node/request'; import { RequestService } from 'vs/platform/request/node/requestService'; -import { generateUuid } from 'vs/base/common/uuid'; import { IURLService } from 'vs/platform/url/common/url'; import { URLChannel } from 'vs/platform/url/common/urlIpc'; import { URLService } from 'vs/platform/url/electron-main/urlService'; @@ -56,7 +56,6 @@ import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc'; import product from 'vs/platform/node/product'; import pkg from 'vs/platform/node/package'; import * as fs from 'original-fs'; -import * as cp from 'child_process'; function quit(accessor: ServicesAccessor, errorOrMessage?: Error | string): void { const logService = accessor.get(ILogService); @@ -341,80 +340,6 @@ function setupIPC(accessor: ServicesAccessor): TPromise { return setup(true); } -function getUnixShellEnvironment(): TPromise { - const promise = new TPromise((c, e) => { - const runAsNode = process.env['ELECTRON_RUN_AS_NODE']; - const noAttach = process.env['ELECTRON_NO_ATTACH_CONSOLE']; - const mark = generateUuid().replace(/-/g, '').substr(0, 12); - const regex = new RegExp(mark + '(.*)' + mark); - - const env = assign({}, process.env, { - ELECTRON_RUN_AS_NODE: '1', - ELECTRON_NO_ATTACH_CONSOLE: '1' - }); - - const command = `'${process.execPath}' -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`; - const child = cp.spawn(process.env.SHELL, ['-ilc', command], { - detached: true, - stdio: ['ignore', 'pipe', process.stderr], - env - }); - - const buffers: Buffer[] = []; - child.on('error', () => c({})); - child.stdout.on('data', b => buffers.push(b)); - - child.on('close', (code: number, signal: any) => { - if (code !== 0) { - return e(new Error('Failed to get environment')); - } - - const raw = Buffer.concat(buffers).toString('utf8'); - const match = regex.exec(raw); - const rawStripped = match ? match[1] : '{}'; - - try { - const env = JSON.parse(rawStripped); - - if (runAsNode) { - env['ELECTRON_RUN_AS_NODE'] = runAsNode; - } else { - delete env['ELECTRON_RUN_AS_NODE']; - } - - if (noAttach) { - env['ELECTRON_NO_ATTACH_CONSOLE'] = noAttach; - } else { - delete env['ELECTRON_NO_ATTACH_CONSOLE']; - } - - c(env); - } catch (err) { - e(err); - } - }); - }); - - // swallow errors - return promise.then(null, () => ({})); -} - -/** - * We eed to get the environment from a user's shell. - * This should only be done when Code itself is not launched - * from within a shell. - */ -function getShellEnvironment(): TPromise { - if (process.env['VSCODE_CLI'] === '1') { - return TPromise.as({}); - } - - if (platform.isWindows) { - return TPromise.as({}); - } - - return getUnixShellEnvironment(); -} function createPaths(environmentService: IEnvironmentService): TPromise { const paths = [ diff --git a/src/vs/code/electron-main/shellEnv.ts b/src/vs/code/electron-main/shellEnv.ts new file mode 100644 index 0000000000000000000000000000000000000000..06009d07cffaae280d50958aadc29b4f8389674e --- /dev/null +++ b/src/vs/code/electron-main/shellEnv.ts @@ -0,0 +1,92 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as cp from 'child_process'; +import { assign } from 'vs/base/common/objects'; +import { generateUuid } from 'vs/base/common/uuid'; +import { TPromise } from 'vs/base/common/winjs.base'; +import { isWindows } from 'vs/base/common/platform'; + + +function getUnixShellEnvironment(): TPromise { + const promise = new TPromise((c, e) => { + const runAsNode = process.env['ELECTRON_RUN_AS_NODE']; + const noAttach = process.env['ELECTRON_NO_ATTACH_CONSOLE']; + const mark = generateUuid().replace(/-/g, '').substr(0, 12); + const regex = new RegExp(mark + '(.*)' + mark); + + const env = assign({}, process.env, { + ELECTRON_RUN_AS_NODE: '1', + ELECTRON_NO_ATTACH_CONSOLE: '1' + }); + + const command = `'${process.execPath}' -p '"${mark}" + JSON.stringify(process.env) + "${mark}"'`; + const child = cp.spawn(process.env.SHELL, ['-ilc', command], { + detached: true, + stdio: ['ignore', 'pipe', process.stderr], + env + }); + + const buffers: Buffer[] = []; + child.on('error', () => c({})); + child.stdout.on('data', b => buffers.push(b)); + + child.on('close', (code: number, signal: any) => { + if (code !== 0) { + return e(new Error('Failed to get environment')); + } + + const raw = Buffer.concat(buffers).toString('utf8'); + const match = regex.exec(raw); + const rawStripped = match ? match[1] : '{}'; + + try { + const env = JSON.parse(rawStripped); + + if (runAsNode) { + env['ELECTRON_RUN_AS_NODE'] = runAsNode; + } else { + delete env['ELECTRON_RUN_AS_NODE']; + } + + if (noAttach) { + env['ELECTRON_NO_ATTACH_CONSOLE'] = noAttach; + } else { + delete env['ELECTRON_NO_ATTACH_CONSOLE']; + } + + c(env); + } catch (err) { + e(err); + } + }); + }); + + // swallow errors + return promise.then(null, () => ({})); +} + + +let _shellEnv: TPromise; + +/** + * We need to get the environment from a user's shell. + * This should only be done when Code itself is not launched + * from within a shell. + */ +export function getShellEnvironment(): TPromise { + if (_shellEnv === undefined) { + if (isWindows) { + _shellEnv = TPromise.as({}); + } else if (process.env['VSCODE_CLI'] === '1') { + _shellEnv = TPromise.as({}); + } else { + _shellEnv = getUnixShellEnvironment(); + } + } + return _shellEnv; +}