@@ -20,7 +20,9 @@ import { WindowsService } from 'vs/platform/windows/electron-main/windowsService
2020import { WindowEventChannel } from 'vs/code/common/windowsIpc' ;
2121import { ILifecycleService , LifecycleService } from 'vs/code/electron-main/lifecycle' ;
2222import { VSCodeMenu } from 'vs/code/electron-main/menus' ;
23- import { IUpdateService , UpdateManager } from 'vs/code/electron-main/update-manager' ;
23+ import { IUpdateService } from 'vs/platform/update/common/update' ;
24+ import { UpdateChannel } from 'vs/platform/update/common/updateIpc' ;
25+ import { UpdateService } from 'vs/platform/update/electron-main/updateService' ;
2426import { Server as ElectronIPCServer } from 'vs/base/parts/ipc/electron-main/ipc.electron-main' ;
2527import { Server , serve , connect } from 'vs/base/parts/ipc/node/ipc.net' ;
2628import { TPromise } from 'vs/base/common/winjs.base' ;
@@ -46,8 +48,13 @@ import { getPathLabel } from 'vs/base/common/labels';
4648import { IURLService } from 'vs/platform/url/common/url' ;
4749import { URLChannel } from 'vs/platform/url/common/urlIpc' ;
4850import { URLService } from 'vs/platform/url/electron-main/urlService' ;
51+ import { ITelemetryService , NullTelemetryService } from 'vs/platform/telemetry/common/telemetry' ;
52+ import { ITelemetryAppenderChannel , TelemetryAppenderClient } from 'vs/platform/telemetry/common/telemetryIpc' ;
53+ import { TelemetryService , ITelemetryServiceConfig } from 'vs/platform/telemetry/common/telemetryService' ;
54+ import { resolveCommonProperties } from 'vs/platform/telemetry/node/commonProperties' ;
55+ import { getDelayedChannel } from 'vs/base/parts/ipc/common/ipc' ;
4956import product from 'vs/platform/product' ;
50-
57+ import pkg from 'vs/platform/package' ;
5158import * as fs from 'original-fs' ;
5259import * as cp from 'child_process' ;
5360import * as path from 'path' ;
@@ -72,13 +79,13 @@ function quit(accessor: ServicesAccessor, arg?: any) {
7279 process . exit ( exitCode ) ; // in main, process.exit === app.exit
7380}
7481
82+ // TODO@Joao wow this is huge, clean up!
7583function main ( accessor : ServicesAccessor , mainIpcServer : Server , userEnv : platform . IProcessEnvironment ) : void {
7684 const instantiationService = accessor . get ( IInstantiationService ) ;
7785 const logService = accessor . get ( ILogService ) ;
7886 const environmentService = accessor . get ( IEnvironmentService ) ;
7987 const windowsMainService = accessor . get ( IWindowsMainService ) ;
8088 const lifecycleService = accessor . get ( ILifecycleService ) ;
81- const updateService = accessor . get ( IUpdateService ) ;
8289 const configurationService = accessor . get ( IConfigurationService ) as ConfigurationService < any > ;
8390 const windowEventChannel = new WindowEventChannel ( windowsMainService ) ;
8491
@@ -147,82 +154,107 @@ function main(accessor: ServicesAccessor, mainIpcServer: Server, userEnv: platfo
147154
148155 let sharedProcessDisposable ;
149156
150- spawnSharedProcess ( initData , options ) . done ( disposable => {
157+ const sharedProcess = spawnSharedProcess ( initData , options ) . then ( disposable => {
151158 sharedProcessDisposable = disposable ;
152-
153- connect ( environmentService . sharedIPCHandle , 'main' )
154- . done ( client => client . registerChannel ( 'windowEvent' , windowEventChannel ) ) ;
159+ return connect ( environmentService . sharedIPCHandle , 'main' ) ;
155160 } ) ;
156161
157- // Make sure we associate the program with the app user model id
158- // This will help Windows to associate the running program with
159- // any shortcut that is pinned to the taskbar and prevent showing
160- // two icons in the taskbar for the same app.
161- if ( platform . isWindows && product . win32AppUserModelId ) {
162- app . setAppUserModelId ( product . win32AppUserModelId ) ;
162+ // Create a new service collection, because the telemetry service
163+ // requires a connection to shared process, which was only established
164+ // now.
165+ const services = new ServiceCollection ( ) ;
166+ services . set ( IUpdateService , new SyncDescriptor ( UpdateService ) ) ;
167+
168+ if ( environmentService . isBuilt && ! environmentService . extensionDevelopmentPath && ! ! product . enableTelemetry ) {
169+ const channel = getDelayedChannel < ITelemetryAppenderChannel > ( sharedProcess . then ( c => c . getChannel ( 'telemetryAppender' ) ) ) ;
170+ const appender = new TelemetryAppenderClient ( channel ) ;
171+ const commonProperties = resolveCommonProperties ( product . commit , pkg . version ) ;
172+ const piiPaths = [ environmentService . appRoot , environmentService . extensionsPath ] ;
173+ const config : ITelemetryServiceConfig = { appender, commonProperties, piiPaths } ;
174+ services . set ( ITelemetryService , new SyncDescriptor ( TelemetryService , config ) ) ;
175+ } else {
176+ services . set ( ITelemetryService , NullTelemetryService ) ;
163177 }
164178
165- function dispose ( ) {
166- if ( mainIpcServer ) {
167- mainIpcServer . dispose ( ) ;
168- mainIpcServer = null ;
169- }
179+ const instantiationService2 = instantiationService . createChild ( services ) ;
170180
171- if ( sharedProcessDisposable ) {
172- sharedProcessDisposable . dispose ( ) ;
173- }
181+ instantiationService2 . invokeFunction ( accessor => {
182+ // Register more Electron IPC services
183+ const updateService = accessor . get ( IUpdateService ) ;
184+ const updateChannel = new UpdateChannel ( updateService ) ;
185+ electronIpcServer . registerChannel ( 'update' , updateChannel ) ;
186+
187+ // Register windowEvent
188+ sharedProcess . done ( client => client . registerChannel ( 'windowEvent' , windowEventChannel ) ) ;
174189
175- if ( windowsMutex ) {
176- windowsMutex . release ( ) ;
190+ // Make sure we associate the program with the app user model id
191+ // This will help Windows to associate the running program with
192+ // any shortcut that is pinned to the taskbar and prevent showing
193+ // two icons in the taskbar for the same app.
194+ if ( platform . isWindows && product . win32AppUserModelId ) {
195+ app . setAppUserModelId ( product . win32AppUserModelId ) ;
177196 }
178197
179- configurationService . dispose ( ) ;
180- }
198+ function dispose ( ) {
199+ if ( mainIpcServer ) {
200+ mainIpcServer . dispose ( ) ;
201+ mainIpcServer = null ;
202+ }
181203
182- // Dispose on app quit
183- app . on ( 'will-quit' , ( ) => {
184- logService . log ( 'App#will-quit: disposing resources' ) ;
204+ if ( sharedProcessDisposable ) {
205+ sharedProcessDisposable . dispose ( ) ;
206+ }
185207
186- dispose ( ) ;
187- } ) ;
208+ if ( windowsMutex ) {
209+ windowsMutex . release ( ) ;
210+ }
188211
189- // Dispose on vscode:exit
190- ipc . on ( 'vscode:exit' , ( event , code : number ) => {
191- logService . log ( 'IPC#vscode:exit' , code ) ;
212+ configurationService . dispose ( ) ;
213+ }
192214
193- dispose ( ) ;
194- process . exit ( code ) ; // in main, process.exit === app.exit
195- } ) ;
215+ // Dispose on app quit
216+ app . on ( 'will-quit' , ( ) => {
217+ logService . log ( 'App#will-quit: disposing resources' ) ;
196218
197- // Lifecycle
198- lifecycleService . ready ( ) ;
219+ dispose ( ) ;
220+ } ) ;
199221
200- // Propagate to clients
201- windowsMainService . ready ( userEnv ) ;
222+ // Dispose on vscode:exit
223+ ipc . on ( 'vscode:exit' , ( event , code : number ) => {
224+ logService . log ( 'IPC#vscode:exit' , code ) ;
202225
203- // Install Menu
204- const menu = instantiationService . createInstance ( VSCodeMenu ) ;
205- menu . ready ( ) ;
226+ dispose ( ) ;
227+ process . exit ( code ) ; // in main, process.exit === app.exit
228+ } ) ;
206229
207- // Install JumpList on Windows (keep updated when windows open)
208- if ( platform . isWindows ) {
209- updateJumpList ( windowsMainService , logService ) ;
210- windowsMainService . onOpen ( ( ) => updateJumpList ( windowsMainService , logService ) ) ;
211- }
230+ // Lifecycle
231+ lifecycleService . ready ( ) ;
212232
213- // Setup auto update
214- updateService . initialize ( ) ;
233+ // Propagate to clients
234+ windowsMainService . ready ( userEnv ) ;
215235
216- // Open our first window
217- if ( environmentService . args [ 'new-window' ] && environmentService . args . _ . length === 0 ) {
218- windowsMainService . open ( { cli : environmentService . args , forceNewWindow : true , forceEmpty : true } ) ; // new window if "-n" was used without paths
219- } else if ( global . macOpenFiles && global . macOpenFiles . length && ( ! environmentService . args . _ || ! environmentService . args . _ . length ) ) {
220- windowsMainService . open ( { cli : environmentService . args , pathsToOpen : global . macOpenFiles } ) ; // mac: open-file event received on startup
221- } else {
222- windowsMainService . open ( { cli : environmentService . args , forceNewWindow : environmentService . args [ 'new-window' ] , diffMode : environmentService . args . diff } ) ; // default: read paths from cli
223- }
236+ // Install Menu
237+ const menu = instantiationService2 . createInstance ( VSCodeMenu ) ;
238+ menu . ready ( ) ;
239+
240+ // Install JumpList on Windows (keep updated when windows open)
241+ if ( platform . isWindows ) {
242+ updateJumpList ( windowsMainService , logService ) ;
243+ windowsMainService . onOpen ( ( ) => updateJumpList ( windowsMainService , logService ) ) ;
244+ }
245+
246+ // Open our first window
247+ if ( environmentService . args [ 'new-window' ] && environmentService . args . _ . length === 0 ) {
248+ windowsMainService . open ( { cli : environmentService . args , forceNewWindow : true , forceEmpty : true } ) ; // new window if "-n" was used without paths
249+ } else if ( global . macOpenFiles && global . macOpenFiles . length && ( ! environmentService . args . _ || ! environmentService . args . _ . length ) ) {
250+ windowsMainService . open ( { cli : environmentService . args , pathsToOpen : global . macOpenFiles } ) ; // mac: open-file event received on startup
251+ } else {
252+ windowsMainService . open ( { cli : environmentService . args , forceNewWindow : environmentService . args [ 'new-window' ] , diffMode : environmentService . args . diff } ) ; // default: read paths from cli
253+ }
254+ } ) ;
224255}
225256
257+ // TODO@Joao TODO@Ben shouldn't this be inside windows service instead?
226258function updateJumpList ( windowsMainService : IWindowsMainService , logService : ILogService ) : void {
227259 const jumpList : Electron . JumpListCategory [ ] = [ ] ;
228260
@@ -448,19 +480,7 @@ function createPaths(environmentService: IEnvironmentService): TPromise<any> {
448480 return TPromise . join ( paths . map ( p => mkdirp ( p ) ) ) as TPromise < any > ;
449481}
450482
451- function start ( ) : void {
452- let args : ParsedArgs ;
453-
454- try {
455- args = parseMainProcessArgv ( process . argv ) ;
456- args = validatePaths ( args ) ;
457- } catch ( err ) {
458- console . error ( err . message ) ;
459- process . exit ( 1 ) ;
460- return ;
461- }
462-
463- // TODO: isolate
483+ function createServices ( args ) : IInstantiationService {
464484 const services = new ServiceCollection ( ) ;
465485
466486 services . set ( IEnvironmentService , new SyncDescriptor ( EnvironmentService , args , process . execPath ) ) ;
@@ -471,10 +491,24 @@ function start(): void {
471491 services . set ( IStorageService , new SyncDescriptor ( StorageService ) ) ;
472492 services . set ( IConfigurationService , new SyncDescriptor ( ConfigurationService ) ) ;
473493 services . set ( IRequestService , new SyncDescriptor ( RequestService ) ) ;
474- services . set ( IUpdateService , new SyncDescriptor ( UpdateManager ) ) ;
475494 services . set ( IURLService , new SyncDescriptor ( URLService , args [ 'open-url' ] ) ) ;
476495
477- const instantiationService = new InstantiationService ( services ) ;
496+ return new InstantiationService ( services ) ;
497+ }
498+
499+ function start ( ) : void {
500+ let args : ParsedArgs ;
501+
502+ try {
503+ args = parseMainProcessArgv ( process . argv ) ;
504+ args = validatePaths ( args ) ;
505+ } catch ( err ) {
506+ console . error ( err . message ) ;
507+ process . exit ( 1 ) ;
508+ return ;
509+ }
510+
511+ const instantiationService = createServices ( args ) ;
478512
479513 // On some platforms we need to manually read from the global environment variables
480514 // and assign them to the process environment (e.g. when doubleclick app on Mac)
0 commit comments