vscode源码分析【四】程序启动的逻辑,最初创建的服务
第一篇: vscode源码分析【一】从源码运行vscode
第二篇:vscode源码分析【二】程序的启动逻辑,第一个窗口是如何创建的
第三篇:vscode源码分析【三】程序的启动逻辑,性能问题的追踪
在第一节中提到的startup函数里(src\vs\code\electron-main\main.ts)
有一个createServices的调用:
const services = new ServiceCollection();
const environmentService = new EnvironmentService(args, process.execPath);
const instanceEnvironment = this.patchEnvironment(environmentService); // Patch `process.env` with the instance's environment
services.set(IEnvironmentService, environmentService);
const logService = new MultiplexLogService([new ConsoleLogMainService(getLogLevel(environmentService)), bufferLogService]);
process.once('exit', () => logService.dispose());
services.set(ILogService, logService);
services.set(IConfigurationService, new ConfigurationService(environmentService.settingsResource));
services.set(ILifecycleService, new SyncDescriptor(LifecycleService));
services.set(IStateService, new SyncDescriptor(StateService));
services.set(IRequestService, new SyncDescriptor(RequestService));
services.set(IDiagnosticsService, new SyncDescriptor(DiagnosticsService));
services.set(IThemeMainService, new SyncDescriptor(ThemeMainService));
services.set(ISignService, new SyncDescriptor(SignService));
return [new InstantiationService(services, true), instanceEnvironment];
在这个方法里,首先创建了一个ServiceCollection(src\vs\platform\instantiation\common\serviceCollection.ts)
这个ServiceCollection内部其实就是一个map对象;不用细说;
我们先看看这些service都是干嘛的
运行环境服务:EnvironmentService
路径:src\vs\platform\environment\node\environmentService.ts
这是一个工具类,
通过这个类可以获取程序的:
启动目录、日志目录、操作系统、配置文件目录、快捷键绑定配置路径....
非常多!
多路日志服务:MultiplexLogService
路径:src\vs\platform\log\common\log.ts
默认是用的控制台输出日志(ConsoleLogMainService)
也是一个工具类
包含trace(查看调用堆栈的),debug,info,warn,error,critical
还有dispose(释放日志服务,进程退出的时候回被调用)和setLevel(设置日志级别)的方法;
在同一个文件里,除了ConsoleLogMainService,
还实现了其他几种日志记录方式,不多做介绍了;
配置服务:ConfigurationService
路径:src\vs\platform\configuration\node\configurationService.ts
从运行环境服务(environmentService)里,拿到配置文件的路径
读出配置文件的内容,然后提供配置项的读写功能;
配置项变更的时候,会有相应的事件触发出来;
生命周期服务:LifecycleService
路径:src\vs\platform\lifecycle\electron-main\lifecycleMain.ts
在这里监听了一系列的electron的事件
比如:
before-quit、window-all-closed、will-quit等
事件被触发的时候,做了下面一些事情
记日志、屏蔽electron默认的处理逻辑、执行自己的逻辑
状态服务:StateService
路径:src\vs\platform\state\node\stateService.ts
在storage.json里记录一些与程序运行状态有关的键值对(也可以删除)
请求服务:RequestService
路径:src\vs\platform\request\electron-main\requestService.ts
使用electron提供的net.request方法,发起请求(支持代理和SSL)
诊断服务:DiagnosticsService
路径:src\vs\platform\diagnostics\electron-main\diagnosticsService.ts
根据不同的操作系统,计算CPU消耗、内存消耗、GPU消耗等
界面主题服务:ThemeMainService
路径:src\vs\platform\theme\electron-main\themeMainService.ts
获取背景色、设置背景色
数据通过stateService保存
程序签名服务:SignService
路径:src\vs\platform\lifecycle\electron-main\lifecycleMain.ts
这个服务为程序的签名提供帮助
缓存了一个vsda的import,目的是为了解决签名时的一个BUG
实例化服务:InstantiationService
这个服务比较特殊,不是在本文一开始所讲的代码里设置的
前面的代码中有这么一行:
return [new InstantiationService(services, true), instanceEnvironment];
这个服务就是在它自身的内部保存到ServiceCollection
constructor(services: ServiceCollection = new ServiceCollection(), strict: boolean = false, parent?: InstantiationService) {
this._services = services;
this._strict = strict;
this._parent = parent;
this._services.set(IInstantiationService, this);
}
这个服务提供了反射、实例化的一些方法;
用于创建具体的类型的实例
服务的初始化工作
服务的对象创建出来之后,有些服务需要完成初始化才能使用
这是在main.ts的initServices中完成的(src\vs\code\electron-main\main.ts)
// Environment service (paths)
const environmentServiceInitialization = Promise.all<void | undefined>([
environmentService.extensionsPath,
environmentService.nodeCachedDataDir,
environmentService.logsPath,
environmentService.globalStorageHome,
environmentService.workspaceStorageHome,
environmentService.backupHome
].map((path): undefined | Promise<void> => path ? mkdirp(path) : undefined));
// Configuration service
const configurationServiceInitialization = configurationService.initialize();
// State service
const stateServiceInitialization = stateService.init();
return Promise.all([environmentServiceInitialization, configurationServiceInitialization, stateServiceInitialization]);
可以看到这个方法里创建了一大堆目录;
创建目录的方法是:(src\vs\base\node\pfs.ts)
const mkdir = async () => {
try {
await promisify(fs.mkdir)(path, mode);
} catch (error) {
// ENOENT: a parent folder does not exist yet
if (error.code === 'ENOENT') {
return Promise.reject(error);
}
// Any other error: check if folder exists and
// return normally in that case if its a folder
try {
const fileStat = await stat(path);
if (!fileStat.isDirectory()) {
return Promise.reject(new Error(`'${path}' exists and is not a directory.`));
}
} catch (statError) {
throw error; // rethrow original error
}
}
};
另外:
最后几个服务的创建(严格说还没有创建)都用到了SyncDescriptor(src\vs\platform\instantiation\common\descriptors.ts)
这里我们解释一下SyncDescriptor,是个简单的泛型类型;
一个它的实例,可以持有一个类型(传入构造函数的类型),这个类型可以等到用的时候再实例化;
vscode源码分析【四】程序启动的逻辑,最初创建的服务的更多相关文章
- vscode源码分析【三】程序的启动逻辑,性能问题的追踪
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 启动追踪 代码文件:src\main.js 如果指定了特定的启动参 ...
- vscode源码分析【九】窗口里的主要元素
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【八】加载第一个画面
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【七】主进程启动消息通信服务
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【六】服务实例化和单例的实现
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- vscode源码分析【五】事件分发机制
第一篇: vscode源码分析[一]从源码运行vscode 第二篇:vscode源码分析[二]程序的启动逻辑,第一个窗口是如何创建的 第三篇:vscode源码分析[三]程序的启动逻辑,性能问题的追踪 ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- ABP源码分析四:Configuration
核心模块的配置 Configuration是ABP中设计比较巧妙的地方.其通过AbpStartupConfiguration,Castle的依赖注入,Dictionary对象和扩展方法很巧妙的实现了配 ...
- ABP源码分析四十七:ABP中的异常处理
ABP 中异常处理的思路是很清晰的.一共五种类型的异常类. AbpInitializationException用于封装ABP初始化过程中出现的异常,只要抛出AbpInitializationExce ...
随机推荐
- arcgis api 4.x for js 自定义叠加图片图层实现地图叠加图片展示(附源码下载)
前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 4.x for js:esri 官网 api,里面详细的介绍 arcgis api 4.x 各个类 ...
- Vue-Cli 3.0 中配置高德地图
vue 中使用高德地图有两种方式 一.vue-amap 组件 官网: https://elemefe.github.io/vue-amap/#/ 开始的时候是打算用这个组件做地图功能的,但是尝试之后存 ...
- PWA 学习笔记(一)
PWA 介绍 概念: PWA(Progressive web apps,渐进式 Web 应用)运用现代 Web API 和传统的渐进式增强策略来创建跨平台 Web 应用程序 它并不是一个快捷方式,而能 ...
- Shell批量SSH免交互登录认证
脚本实现功能:批量或单个SSH免交互登录认证 脚本应用场景:当部署集群时,大多数实现要配置好管理节点与从节点的SSH免交互登录,针对这样的情况,写了下面脚本,简化工作. 脚本支持系统:Ubuntu和C ...
- cURL无法访问TLS网站故障解决
大多数人都厌烦使用老旧的系统,无论软件还是硬件.但有的时候又不得不困守其中,坚持延续着系统的寿命,或者还需要点几柱香,祈求神佛的护佑. Linux是一个模块化极好的操作系统,得益于此,当其中有组件落伍 ...
- C++ std::stack 基本用法
#include <iostream> #include <string> #include <stack> // https://zh.cppreference. ...
- Maven使用之packaging类型
项目的打包类型:pom.jar.war 项目中一般使用maven进行模块管理,每个模块下对应都有一个pom文件,pom文件中维护了各模块之间的依赖和继承关系.项目模块化可以将通用的部分抽离出来,方便重 ...
- Linux下MySQL数据库的my.cnf配置文件,解决中文乱码问题
系统 CentOS 7.7 MySQL - 5.7.28文件放置目录:/etc/文件权限:644解决问题:存储中文数据乱码 # For advice on how to change settings ...
- CSS权重的进制问题
这是复习篇的第一个知识点,(CSS权重进制在IE6为256,后来扩大到了65536.而现代浏览器则采用更大的数量)在说这个知识点之前我们先来看一个例子 <!DOCTYPE html> &l ...
- (四十四)c#Winform自定义控件-水波-HZHControls
官网 http://www.hzhcontrols.com 前提 入行已经7,8年了,一直想做一套漂亮点的自定义控件,于是就有了本系列文章. GitHub:https://github.com/kww ...