diff --git a/src/vs/code/electron-main/main.ts b/src/vs/code/electron-main/main.ts index e75241ab340..b6465d6db5c 100644 --- a/src/vs/code/electron-main/main.ts +++ b/src/vs/code/electron-main/main.ts @@ -22,7 +22,7 @@ import { Server, serve, connect } from 'vs/base/parts/ipc/node/ipc.net'; import { TPromise } from 'vs/base/common/winjs.base'; import { AskpassChannel } from 'vs/workbench/parts/git/common/gitIpc'; import { GitAskpassService } from 'vs/workbench/parts/git/electron-main/askpassService'; -import { spawnSharedProcess } from 'vs/code/electron-main/sharedProcess'; +import { spawnSharedProcess } from 'vs/code/node/sharedProcess'; import { Mutex } from 'windows-mutex'; import { LaunchService, ILaunchChannel, LaunchChannel, LaunchChannelClient } from './launch'; import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; @@ -66,6 +66,7 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce const instantiationService = accessor.get(IInstantiationService); const logService = accessor.get(ILogService); const envService = accessor.get(IEnvService); + const environmentService = accessor.get(IEnvironmentService); const windowsService = accessor.get(IWindowsService); const lifecycleService = accessor.get(ILifecycleService); const updateService = accessor.get(IUpdateService); @@ -121,10 +122,13 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: IProce electronIpcServer.registerChannel('url', urlChannel); // Spawn shared process - const sharedProcess = spawnSharedProcess({ + const initData = { args: environmentService.args }; + const options = { allowOutput: !envService.isBuilt || envService.cliArgs.verbose, debugPort: envService.isBuilt ? null : 5871 - }); + }; + + const sharedProcess = spawnSharedProcess(initData, options); // Make sure we associate the program with the app user model id // This will help Windows to associate the running program with diff --git a/src/vs/code/electron-main/sharedProcess.ts b/src/vs/code/node/sharedProcess.ts similarity index 74% rename from src/vs/code/electron-main/sharedProcess.ts rename to src/vs/code/node/sharedProcess.ts index 3348239f100..1f65413ac58 100644 --- a/src/vs/code/electron-main/sharedProcess.ts +++ b/src/vs/code/node/sharedProcess.ts @@ -7,6 +7,11 @@ import * as cp from 'child_process'; import URI from 'vs/base/common/uri'; import { IDisposable } from 'vs/base/common/lifecycle'; import { assign } from 'vs/base/common/objects'; +import { ParsedArgs } from 'vs/platform/environment/node/argv'; + +export interface ISharedProcessInitData { + args: ParsedArgs; +} export interface ISharedProcessOptions { allowOutput?: boolean; @@ -15,7 +20,7 @@ export interface ISharedProcessOptions { const boostrapPath = URI.parse(require.toUrl('bootstrap')).fsPath; -function _spawnSharedProcess(options: ISharedProcessOptions): cp.ChildProcess { +function _spawnSharedProcess(initData: ISharedProcessInitData, options: ISharedProcessOptions): cp.ChildProcess { const execArgv = []; const env = assign({}, process.env, { AMD_ENTRYPOINT: 'vs/code/node/sharedProcessMain' @@ -32,12 +37,12 @@ function _spawnSharedProcess(options: ISharedProcessOptions): cp.ChildProcess { const result = cp.fork(boostrapPath, ['--type=SharedProcess'], { env, execArgv }); // handshake - result.once('message', () => result.send('hey')); + result.once('message', () => result.send(initData)); return result; } -export function spawnSharedProcess(options: ISharedProcessOptions = {}): IDisposable { +export function spawnSharedProcess(initData: ISharedProcessInitData, options: ISharedProcessOptions = {}): IDisposable { let spawnCount = 0; let child: cp.ChildProcess; @@ -46,7 +51,7 @@ export function spawnSharedProcess(options: ISharedProcessOptions = {}): IDispos return; } - child = _spawnSharedProcess(options); + child = _spawnSharedProcess(initData, options); child.on('exit', spawn); }; diff --git a/src/vs/code/node/sharedProcessMain.ts b/src/vs/code/node/sharedProcessMain.ts index d7ede781b9b..deeda5b65f7 100644 --- a/src/vs/code/node/sharedProcessMain.ts +++ b/src/vs/code/node/sharedProcessMain.ts @@ -14,7 +14,6 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors'; import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService'; import { IEnvironmentService } from 'vs/platform/environment/common/environment'; import { EnvironmentService } from 'vs/platform/environment/node/environmentService'; -import { parseArgs } from 'vs/platform/environment/node/argv'; import { IEventService } from 'vs/platform/event/common/event'; import { EventService } from 'vs/platform/event/common/eventService'; import { ExtensionManagementChannel } from 'vs/platform/extensionManagement/common/extensionManagementIpc'; @@ -30,6 +29,7 @@ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProper import { TelemetryAppenderChannel } from 'vs/platform/telemetry/common/telemetryIpc'; import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService'; import { AppInsightsAppender } from 'vs/platform/telemetry/node/appInsightsAppender'; +import { ISharedProcessInitData } from './sharedProcess'; function quit(err?: Error) { if (err) { @@ -54,11 +54,11 @@ function setupPlanB(parentPid: number): void { const eventPrefix = 'monacoworkbench'; -function main(server: Server): void { +function main(server: Server, initData: ISharedProcessInitData): void { const services = new ServiceCollection(); services.set(IEventService, new SyncDescriptor(EventService)); - services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, parseArgs(process.argv), process.execPath)); + services.set(IEnvironmentService, new SyncDescriptor(EnvironmentService, initData.args, process.execPath)); services.set(IConfigurationService, new SyncDescriptor(ConfigurationService)); services.set(IRequestService, new SyncDescriptor(RequestService)); @@ -147,8 +147,8 @@ function setupIPC(hook: string): TPromise { return setup(true); } -function handshake(): TPromise { - return new TPromise((c, e) => { +function handshake(): TPromise { + return new TPromise((c, e) => { process.once('message', c); process.once('error', e); process.send('hello'); @@ -156,6 +156,6 @@ function handshake(): TPromise { } TPromise.join([setupIPC(process.env['VSCODE_SHARED_IPC_HOOK']), handshake()]) - .then(r => main(r[0])) + .then(r => main(r[0], r[1])) .then(() => setupPlanB(process.env['VSCODE_PID'])) .done(null, quit); \ No newline at end of file diff --git a/src/vs/platform/environment/common/environment.ts b/src/vs/platform/environment/common/environment.ts index 37c65bc3db2..57d50f59025 100644 --- a/src/vs/platform/environment/common/environment.ts +++ b/src/vs/platform/environment/common/environment.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import {ParsedArgs} from 'vs/platform/environment/node/argv'; import { createDecorator } from 'vs/platform/instantiation/common/instantiation'; export const IEnvironmentService = createDecorator('environmentService'); @@ -10,6 +11,8 @@ export const IEnvironmentService = createDecorator('environ export interface IEnvironmentService { _serviceBrand: any; + args: ParsedArgs; + execPath: string; appRoot: string; diff --git a/src/vs/platform/environment/node/environmentService.ts b/src/vs/platform/environment/node/environmentService.ts index 5e2ea603787..11a66c7a1d5 100644 --- a/src/vs/platform/environment/node/environmentService.ts +++ b/src/vs/platform/environment/node/environmentService.ts @@ -54,6 +54,8 @@ export class EnvironmentService implements IEnvironmentService { _serviceBrand: any; + get args(): ParsedArgs { return this._args; } + @memoize get appRoot(): string { return path.dirname(URI.parse(require.toUrl('')).fsPath); } @@ -63,7 +65,7 @@ export class EnvironmentService implements IEnvironmentService { get userHome(): string { return path.join(os.homedir(), product.dataFolderName); } @memoize - get userDataPath(): string { return this.args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform); } + get userDataPath(): string { return this._args['user-data-dir'] || paths.getDefaultUserDataPath(process.platform); } @memoize get appSettingsHome(): string { return path.join(this.userDataPath, 'User'); } @@ -75,20 +77,20 @@ export class EnvironmentService implements IEnvironmentService { get appKeybindingsPath(): string { return path.join(this.appSettingsHome, 'keybindings.json'); } @memoize - get extensionsPath(): string { return path.normalize(this.args.extensionHomePath || path.join(this.userHome, 'extensions')); } + get extensionsPath(): string { return path.normalize(this._args.extensionHomePath || path.join(this.userHome, 'extensions')); } - get extensionDevelopmentPath(): string { return this.args.extensionDevelopmentPath; } + get extensionDevelopmentPath(): string { return this._args.extensionDevelopmentPath; } - get extensionTestsPath(): string { return this.args.extensionTestsPath; } - get disableExtensions(): boolean { return this.args['disable-extensions']; } + get extensionTestsPath(): string { return this._args.extensionTestsPath; } + get disableExtensions(): boolean { return this._args['disable-extensions']; } @memoize - get debugExtensionHost(): { port: number; break: boolean; } { return parseExtensionHostPort(this.args, this.isBuilt); } + get debugExtensionHost(): { port: number; break: boolean; } { return parseExtensionHostPort(this._args, this.isBuilt); } get isBuilt(): boolean { return !process.env['VSCODE_DEV']; } - get verbose(): boolean { return this.args.verbose; } - get performance(): boolean { return this.args.performance; } - get logExtensionHostCommunication(): boolean { return this.args.logExtensionHostCommunication; } + get verbose(): boolean { return this._args.verbose; } + get performance(): boolean { return this._args.performance; } + get logExtensionHostCommunication(): boolean { return this._args.logExtensionHostCommunication; } @memoize get mainIPCHandle(): string { return `${ IPCHandlePrefix }-${ pkg.version }${ IPCHandleSuffix }`; } @@ -96,7 +98,7 @@ export class EnvironmentService implements IEnvironmentService { @memoize get sharedIPCHandle(): string { return `${ IPCHandlePrefix }-${ pkg.version }-shared${ IPCHandleSuffix }`; } - constructor(private args: ParsedArgs, private _execPath: string) {} + constructor(private _args: ParsedArgs, private _execPath: string) {} } export function parseExtensionHostPort(args: ParsedArgs, isBuild: boolean): { port: number; break: boolean; } { diff --git a/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts b/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts index af6b0034bb0..3728de76e7a 100644 --- a/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts +++ b/src/vs/workbench/parts/extensions/electron-browser/extensionsWorkbenchExtension.ts @@ -51,7 +51,7 @@ export class ExtensionsWorkbenchExtension implements IWorkbenchContribution { } private install(extensions: string[]): TPromise { - return TPromise.join(extensions.map(extPath => this.extensionManagementService.install(extPath))) + return TPromise.join(extensions.map(extPath => this.extensionManagementService.install(extPath))) .then(() => { this.messageService.show( Severity.Info,