提交 be24140c 编写于 作者: B Benjamin Pasero

debt - decouple app from main code

上级 1744078c
/*---------------------------------------------------------------------------------------------
* 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 { app, ipcMain as ipc, BrowserWindow } from 'electron';
import * as platform from 'vs/base/common/platform';
import { OpenContext } from 'vs/code/common/windows';
import { IWindowsMainService, WindowsManager } from 'vs/code/electron-main/windows';
import { IWindowsService } from 'vs/platform/windows/common/windows';
import { WindowsChannel } from 'vs/platform/windows/common/windowsIpc';
import { WindowsService } from 'vs/platform/windows/electron-main/windowsService';
import { 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';
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main';
import { Server, connect, Client } from 'vs/base/parts/ipc/node/ipc.net';
import { AskpassChannel } from 'vs/workbench/parts/git/common/gitIpc';
import { GitAskpassService } from 'vs/workbench/parts/git/electron-main/askpassService';
import { SharedProcess } from 'vs/code/electron-main/sharedProcess';
import { Mutex } from 'windows-mutex';
import { LaunchService, LaunchChannel, ILaunchService } from './launch';
import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ILogService } from 'vs/code/electron-main/log';
import { IStorageService } from 'vs/code/electron-main/storage';
import { IBackupMainService } from 'vs/platform/backup/common/backup';
import { BackupChannel } from 'vs/platform/backup/common/backupIpc';
import { IEnvironmentService } from 'vs/platform/environment/common/environment';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IURLService } from 'vs/platform/url/common/url';
import { URLChannel } from 'vs/platform/url/common/urlIpc';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
import { resolveCommonProperties, machineIdStorageKey, machineIdIpcChannel } from 'vs/platform/telemetry/node/commonProperties';
import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc';
import product from 'vs/platform/node/product';
import pkg from 'vs/platform/node/package';
import { IDisposable, dispose } from "vs/base/common/lifecycle";
import { ConfigurationService } from "vs/platform/configuration/node/configurationService";
import { TPromise } from "vs/base/common/winjs.base";
export class VSCodeApplication {
private toDispose: IDisposable[];
private windowsMainService: IWindowsMainService;
private electronIpcServer: ElectronIPCServer;
private sharedProcess: SharedProcess;
private sharedProcessClient: TPromise<Client>;
constructor(
private mainIpcServer: Server,
private userEnv: platform.IProcessEnvironment,
@IInstantiationService private instantiationService: IInstantiationService,
@ILogService private logService: ILogService,
@IEnvironmentService private environmentService: IEnvironmentService,
@ILifecycleService private lifecycleService: ILifecycleService,
@IConfigurationService private configurationService: ConfigurationService<any>,
@IStorageService private storageService: IStorageService
) {
this.toDispose = [mainIpcServer, configurationService];
this.registerListeners();
}
private registerListeners(): void {
// We handle uncaught exceptions here to prevent electron from opening a dialog to the user
process.on('uncaughtException', (err: any) => {
if (err) {
// take only the message and stack property
const friendlyError = {
message: err.message,
stack: err.stack
};
// handle on client side
if (this.windowsMainService) {
this.windowsMainService.sendToFocused('vscode:reportError', JSON.stringify(friendlyError));
}
}
console.error('[uncaught exception in main]: ' + err);
if (err.stack) {
console.error(err.stack);
}
});
ipc.on(machineIdIpcChannel, (event, machineId: string) => {
this.logService.log('IPC#vscode-machineId');
this.storageService.setItem(machineIdStorageKey, machineId);
});
ipc.on('vscode:fetchShellEnv', (event, windowId) => {
const win = BrowserWindow.fromId(windowId);
getShellEnvironment().then(shellEnv => {
win.webContents.send('vscode:acceptShellEnv', shellEnv);
}, err => {
win.webContents.send('vscode:acceptShellEnv', {});
console.error('Error fetching shell env', err);
});
});
app.on('will-quit', () => {
this.logService.log('App#will-quit: disposing resources');
this.dispose();
});
ipc.on('vscode:exit', (event, code: number) => {
this.logService.log('IPC#vscode:exit', code);
this.dispose();
this.lifecycleService.kill(code);
});
}
public startup(): void {
this.logService.log('Starting VS Code in verbose mode');
this.logService.log(`from: ${this.environmentService.appRoot}`);
this.logService.log('args:', this.environmentService.args);
// Setup Windows mutex
let windowsMutex: Mutex = null;
if (platform.isWindows) {
try {
const Mutex = (require.__$__nodeRequire('windows-mutex') as any).Mutex;
windowsMutex = new Mutex(product.win32MutexName);
this.toDispose.push({ dispose: () => windowsMutex.release() });
} catch (e) {
// noop
}
}
// Make sure we associate the program with the app user model id
// This will help Windows to associate the running program with
// any shortcut that is pinned to the taskbar and prevent showing
// two icons in the taskbar for the same app.
if (platform.isWindows && product.win32AppUserModelId) {
app.setAppUserModelId(product.win32AppUserModelId);
}
// Register Main IPC connections
const askpassService = new GitAskpassService();
const askpassChannel = new AskpassChannel(askpassService);
this.mainIpcServer.registerChannel('askpass', askpassChannel);
// Create Electron IPC Server
this.electronIpcServer = new ElectronIPCServer();
// Spawn shared process
this.sharedProcess = new SharedProcess(this.environmentService, this.userEnv);
this.toDispose.push(this.sharedProcess);
this.sharedProcessClient = this.sharedProcess.whenReady()
.then(() => connect(this.environmentService.sharedIPCHandle, 'main'));
// Services
const appInstantiationService = this.initServices();
// Do Startup
appInstantiationService.invokeFunction(accessor => this.doStartup(accessor));
}
private initServices(): IInstantiationService {
const services = new ServiceCollection();
services.set(IUpdateService, new SyncDescriptor(UpdateService));
services.set(IWindowsMainService, new SyncDescriptor(WindowsManager));
services.set(IWindowsService, new SyncDescriptor(WindowsService, this.sharedProcess));
services.set(ILaunchService, new SyncDescriptor(LaunchService));
// Telemtry
if (this.environmentService.isBuilt && !this.environmentService.isExtensionDevelopment && !!product.enableTelemetry) {
const channel = getDelayedChannel<ITelemetryAppenderChannel>(this.sharedProcessClient.then(c => c.getChannel('telemetryAppender')));
const appender = new TelemetryAppenderClient(channel);
const commonProperties = resolveCommonProperties(product.commit, pkg.version)
.then(result => Object.defineProperty(result, 'common.machineId', {
get: () => this.storageService.getItem(machineIdStorageKey),
enumerable: true
}));
const piiPaths = [this.environmentService.appRoot, this.environmentService.extensionsPath];
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths };
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config));
} else {
services.set(ITelemetryService, NullTelemetryService);
}
return this.instantiationService.createChild(services);
}
private doStartup(accessor: ServicesAccessor): void {
const appInstantiationService = accessor.get(IInstantiationService);
// TODO@Joao: unfold this
this.windowsMainService = accessor.get(IWindowsMainService);
// TODO@Joao: so ugly...
this.windowsMainService.onWindowClose(() => {
if (!platform.isMacintosh && this.windowsMainService.getWindowCount() === 0) {
this.sharedProcess.dispose();
}
});
// Register more Main IPC services
const launchService = accessor.get(ILaunchService);
const launchChannel = new LaunchChannel(launchService);
this.mainIpcServer.registerChannel('launch', launchChannel);
// Register more Electron IPC services
const updateService = accessor.get(IUpdateService);
const updateChannel = new UpdateChannel(updateService);
this.electronIpcServer.registerChannel('update', updateChannel);
const urlService = accessor.get(IURLService);
const urlChannel = appInstantiationService.createInstance(URLChannel, urlService);
this.electronIpcServer.registerChannel('url', urlChannel);
const backupService = accessor.get(IBackupMainService);
const backupChannel = appInstantiationService.createInstance(BackupChannel, backupService);
this.electronIpcServer.registerChannel('backup', backupChannel);
const windowsService = accessor.get(IWindowsService);
const windowsChannel = new WindowsChannel(windowsService);
this.electronIpcServer.registerChannel('windows', windowsChannel);
this.sharedProcessClient.done(client => client.registerChannel('windows', windowsChannel));
// Lifecycle
this.lifecycleService.ready();
// Propagate to clients
this.windowsMainService.ready(this.userEnv);
// Open our first window
const args = this.environmentService.args;
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
if (args['new-window'] && args._.length === 0) {
this.windowsMainService.open({ context, cli: args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths
} else if (global.macOpenFiles && global.macOpenFiles.length && (!args._ || !args._.length)) {
this.windowsMainService.open({ context: OpenContext.DOCK, cli: args, pathsToOpen: global.macOpenFiles, initialStartup: true }); // mac: open-file event received on startup
} else {
this.windowsMainService.open({ context, cli: args, forceNewWindow: args['new-window'] || (!args._.length && args['unity-launch']), diffMode: args.diff, initialStartup: true }); // default: read paths from cli
}
// Install Menu
appInstantiationService.createInstance(VSCodeMenu);
// Jump List
this.windowsMainService.updateWindowsJumpList();
this.windowsMainService.onRecentPathsChange(() => this.windowsMainService.updateWindowsJumpList());
// Start shared process here
this.sharedProcess.spawn();
}
private dispose(): void {
this.toDispose = dispose(this.toDispose);
}
}
\ No newline at end of file
......@@ -5,31 +5,16 @@
'use strict';
import { app, ipcMain as ipc, BrowserWindow } from 'electron';
import { app } from 'electron';
import { assign } from 'vs/base/common/objects';
import * as platform from 'vs/base/common/platform';
import { parseMainProcessArgv } from 'vs/platform/environment/node/argv';
import { mkdirp } from 'vs/base/node/pfs';
import { validatePaths } from 'vs/code/electron-main/paths';
import { OpenContext } from 'vs/code/common/windows';
import { IWindowsMainService, WindowsManager } from 'vs/code/electron-main/windows';
import { IWindowsService } from 'vs/platform/windows/common/windows';
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';
import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main';
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 { SharedProcess } from 'vs/code/electron-main/sharedProcess';
import { Mutex } from 'windows-mutex';
import { LaunchService, ILaunchChannel, LaunchChannel, LaunchChannelClient, ILaunchService } from './launch';
import { ILaunchChannel, LaunchChannelClient } from './launch';
import { ServicesAccessor, IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { InstantiationService } from 'vs/platform/instantiation/common/instantiationService';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
......@@ -37,7 +22,6 @@ import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
import { ILogService, MainLogService } from 'vs/code/electron-main/log';
import { IStorageService, StorageService } from 'vs/code/electron-main/storage';
import { IBackupMainService } from 'vs/platform/backup/common/backup';
import { BackupChannel } from 'vs/platform/backup/common/backupIpc';
import { BackupMainService } from 'vs/platform/backup/electron-main/backupMainService';
import { IEnvironmentService, ParsedArgs } from 'vs/platform/environment/common/environment';
import { EnvironmentService } from 'vs/platform/environment/node/environmentService';
......@@ -46,238 +30,52 @@ import { ConfigurationService } from 'vs/platform/configuration/node/configurati
import { IRequestService } from 'vs/platform/request/node/request';
import { RequestService } from 'vs/platform/request/electron-main/requestService';
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';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
import { ITelemetryAppenderChannel, TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc';
import { TelemetryService, ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService';
import { resolveCommonProperties, machineIdStorageKey, machineIdIpcChannel } from 'vs/platform/telemetry/node/commonProperties';
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 { VSCodeApplication } from "vs/code/electron-main/app";
ipc.on('vscode:fetchShellEnv', (event, windowId) => {
const win = BrowserWindow.fromId(windowId);
getShellEnvironment().then(shellEnv => {
win.webContents.send('vscode:acceptShellEnv', shellEnv);
}, err => {
win.webContents.send('vscode:acceptShellEnv', {});
console.error('Error fetching shell env', err);
});
});
function quit(accessor: ServicesAccessor, errorOrMessage?: Error | string): void {
const logService = accessor.get(ILogService);
const lifecycleService = accessor.get(ILifecycleService);
let exitCode = 0;
if (typeof errorOrMessage === 'string') {
logService.log(errorOrMessage);
} else if (errorOrMessage) {
exitCode = 1; // signal error to the outside
if (errorOrMessage.stack) {
console.error(errorOrMessage.stack);
} else {
console.error('Startup error: ' + errorOrMessage.toString());
}
}
lifecycleService.kill(exitCode);
}
// TODO@Joao wow this is huge, clean up!
function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platform.IProcessEnvironment): void {
const instantiationService = accessor.get(IInstantiationService);
const logService = accessor.get(ILogService);
const environmentService = accessor.get(IEnvironmentService);
const lifecycleService = accessor.get(ILifecycleService);
const configurationService = accessor.get(IConfigurationService) as ConfigurationService<any>;
const storageService = accessor.get(IStorageService);
let windowsMainService: IWindowsMainService;
// We handle uncaught exceptions here to prevent electron from opening a dialog to the user
process.on('uncaughtException', (err: any) => {
if (err) {
// take only the message and stack property
const friendlyError = {
message: err.message,
stack: err.stack
};
// handle on client side
if (windowsMainService) {
windowsMainService.sendToFocused('vscode:reportError', JSON.stringify(friendlyError));
}
}
console.error('[uncaught exception in main]: ' + err);
if (err.stack) {
console.error(err.stack);
}
});
ipc.on(machineIdIpcChannel, (event, machineId: string) => {
logService.log('IPC#vscode-machineId');
storageService.setItem(machineIdStorageKey, machineId);
});
logService.log('Starting VS Code in verbose mode');
logService.log(`from: ${environmentService.appRoot}`);
logService.log('args:', environmentService.args);
// Setup Windows mutex
let windowsMutex: Mutex = null;
if (platform.isWindows) {
try {
const Mutex = (<any>require.__$__nodeRequire('windows-mutex')).Mutex;
windowsMutex = new Mutex(product.win32MutexName);
} catch (e) {
// noop
}
}
// Register Main IPC services
const askpassService = new GitAskpassService();
const askpassChannel = new AskpassChannel(askpassService);
mainIpcServer.registerChannel('askpass', askpassChannel);
// Create Electron IPC Server
const electronIpcServer = new ElectronIPCServer();
// Spawn shared process
const sharedProcess = new SharedProcess(environmentService, userEnv);
const sharedProcessClient = sharedProcess.whenReady()
.then(() => connect(environmentService.sharedIPCHandle, 'main'));
// Create a new service collection, because the telemetry service
// requires a connection to shared process, which was only established
// now.
const services = new ServiceCollection();
//
// Main Startup Sequence
//
(function () {
let args: ParsedArgs;
services.set(IUpdateService, new SyncDescriptor(UpdateService));
services.set(IWindowsMainService, new SyncDescriptor(WindowsManager));
services.set(IWindowsService, new SyncDescriptor(WindowsService, sharedProcess));
services.set(ILaunchService, new SyncDescriptor(LaunchService));
try {
args = parseMainProcessArgv(process.argv);
args = validatePaths(args);
} catch (err) {
console.error(err.message);
app.exit(1);
if (environmentService.isBuilt && !environmentService.isExtensionDevelopment && !!product.enableTelemetry) {
const channel = getDelayedChannel<ITelemetryAppenderChannel>(sharedProcessClient.then(c => c.getChannel('telemetryAppender')));
const appender = new TelemetryAppenderClient(channel);
const commonProperties = resolveCommonProperties(product.commit, pkg.version)
.then(result => Object.defineProperty(result, 'common.machineId', {
get: () => storageService.getItem(machineIdStorageKey),
enumerable: true
}));
const piiPaths = [environmentService.appRoot, environmentService.extensionsPath];
const config: ITelemetryServiceConfig = { appender, commonProperties, piiPaths };
services.set(ITelemetryService, new SyncDescriptor(TelemetryService, config));
} else {
services.set(ITelemetryService, NullTelemetryService);
return;
}
const instantiationService2 = instantiationService.createChild(services);
instantiationService2.invokeFunction(accessor => {
// TODO@Joao: unfold this
windowsMainService = accessor.get(IWindowsMainService);
// TODO@Joao: so ugly...
windowsMainService.onWindowClose(() => {
if (!platform.isMacintosh && windowsMainService.getWindowCount() === 0) {
sharedProcess.dispose();
}
});
// Register more Main IPC services
const launchService = accessor.get(ILaunchService);
const launchChannel = new LaunchChannel(launchService);
mainIpcServer.registerChannel('launch', launchChannel);
// Register more Electron IPC services
const updateService = accessor.get(IUpdateService);
const updateChannel = new UpdateChannel(updateService);
electronIpcServer.registerChannel('update', updateChannel);
const urlService = accessor.get(IURLService);
const urlChannel = instantiationService2.createInstance(URLChannel, urlService);
electronIpcServer.registerChannel('url', urlChannel);
const backupService = accessor.get(IBackupMainService);
const backupChannel = instantiationService2.createInstance(BackupChannel, backupService);
electronIpcServer.registerChannel('backup', backupChannel);
const windowsService = accessor.get(IWindowsService);
const windowsChannel = new WindowsChannel(windowsService);
electronIpcServer.registerChannel('windows', windowsChannel);
sharedProcessClient.done(client => client.registerChannel('windows', windowsChannel));
// Make sure we associate the program with the app user model id
// This will help Windows to associate the running program with
// any shortcut that is pinned to the taskbar and prevent showing
// two icons in the taskbar for the same app.
if (platform.isWindows && product.win32AppUserModelId) {
app.setAppUserModelId(product.win32AppUserModelId);
}
function dispose() {
if (mainIpcServer) {
mainIpcServer.dispose();
mainIpcServer = null;
}
if (windowsMutex) {
windowsMutex.release();
}
configurationService.dispose();
sharedProcess.dispose();
}
// Dispose on app quit
app.on('will-quit', () => {
logService.log('App#will-quit: disposing resources');
dispose();
});
// Dispose on vscode:exit
ipc.on('vscode:exit', (event, code: number) => {
logService.log('IPC#vscode:exit', code);
dispose();
lifecycleService.kill(code);
});
// Lifecycle
lifecycleService.ready();
// Propagate to clients
windowsMainService.ready(userEnv);
// Open our first window
const context = !!process.env['VSCODE_CLI'] ? OpenContext.CLI : OpenContext.DESKTOP;
if (environmentService.args['new-window'] && environmentService.args._.length === 0) {
windowsMainService.open({ context, cli: environmentService.args, forceNewWindow: true, forceEmpty: true, initialStartup: true }); // new window if "-n" was used without paths
} else if (global.macOpenFiles && global.macOpenFiles.length && (!environmentService.args._ || !environmentService.args._.length)) {
windowsMainService.open({ context: OpenContext.DOCK, cli: environmentService.args, pathsToOpen: global.macOpenFiles, initialStartup: true }); // mac: open-file event received on startup
} else {
windowsMainService.open({ context, cli: environmentService.args, forceNewWindow: environmentService.args['new-window'] || (!environmentService.args._.length && environmentService.args['unity-launch']), diffMode: environmentService.args.diff, initialStartup: true }); // default: read paths from cli
}
const instantiationService = createServices(args);
// Install Menu
instantiationService2.createInstance(VSCodeMenu);
return instantiationService.invokeFunction(accessor => {
// Jump List
windowsMainService.updateWindowsJumpList();
windowsMainService.onRecentPathsChange(() => windowsMainService.updateWindowsJumpList());
// Patch `process.env` with the instance's environment
const environmentService = accessor.get(IEnvironmentService);
const instanceEnv: typeof process.env = {
VSCODE_PID: String(process.pid),
VSCODE_IPC_HOOK: environmentService.mainIPCHandle,
VSCODE_NLS_CONFIG: process.env['VSCODE_NLS_CONFIG']
};
assign(process.env, instanceEnv);
// Start shared process here
sharedProcess.spawn();
});
}
// Startup
return instantiationService.invokeFunction(a => createPaths(a.get(IEnvironmentService)))
.then(() => instantiationService.invokeFunction(setupIPC))
.then(mainIpcServer => {
const app = instantiationService.createInstance(VSCodeApplication, mainIpcServer, instanceEnv);
app.startup();
});
}).done(null, err => instantiationService.invokeFunction(quit, err));
})();
//
// Helpers
//
function setupIPC(accessor: ServicesAccessor): TPromise<Server> {
const logService = accessor.get(ILogService);
const environmentService = accessor.get(IEnvironmentService);
......@@ -364,7 +162,6 @@ function setupIPC(accessor: ServicesAccessor): TPromise<Server> {
return setup(true);
}
function createPaths(environmentService: IEnvironmentService): TPromise<any> {
const paths = [
environmentService.appSettingsHome,
......@@ -389,36 +186,21 @@ function createServices(args: ParsedArgs): IInstantiationService {
return new InstantiationService(services, true);
}
function start(): void {
let args: ParsedArgs;
try {
args = parseMainProcessArgv(process.argv);
args = validatePaths(args);
} catch (err) {
console.error(err.message);
app.exit(1);
function quit(accessor: ServicesAccessor, errorOrMessage?: Error | string): void {
const logService = accessor.get(ILogService);
const lifecycleService = accessor.get(ILifecycleService);
return;
let exitCode = 0;
if (typeof errorOrMessage === 'string') {
logService.log(errorOrMessage);
} else if (errorOrMessage) {
exitCode = 1; // signal error to the outside
if (errorOrMessage.stack) {
console.error(errorOrMessage.stack);
} else {
console.error('Startup error: ' + errorOrMessage.toString());
}
}
const instantiationService = createServices(args);
return instantiationService.invokeFunction(accessor => {
const environmentService = accessor.get(IEnvironmentService);
const instanceEnv: typeof process.env = {
VSCODE_PID: String(process.pid),
VSCODE_IPC_HOOK: environmentService.mainIPCHandle,
VSCODE_NLS_CONFIG: process.env['VSCODE_NLS_CONFIG']
};
// Patch `process.env` with the instance's environment
assign(process.env, instanceEnv);
return instantiationService.invokeFunction(a => createPaths(a.get(IEnvironmentService)))
.then(() => instantiationService.invokeFunction(setupIPC))
.then(mainIpcServer => instantiationService.invokeFunction(main, mainIpcServer, instanceEnv));
}).done(null, err => instantiationService.invokeFunction(quit, err));
}
start();
lifecycleService.kill(exitCode);
}
\ No newline at end of file
......@@ -19,7 +19,6 @@ const electron = require('electron');
const remote = electron.remote;
const ipc = electron.ipcRenderer;
process.lazyEnv = new Promise(function (resolve) {
ipc.once('vscode:acceptShellEnv', function (event, shellEnv) {
assign(process.env, shellEnv);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册