目录
- ini配置文件
- 环境变量
- 注册表
缘起
我在写引擎的时候遇到一个问题,就是我的引擎有一些配置文件放在一些地方,程序怎么知道它们放在哪里呢?
我当然可以在程序里硬编码一个路径,但是如果别人拷贝了我的引擎,放在了他自己喜欢的地方,那么我在程序里硬编码的路径当然是错误的。
所以我的引擎作为一个应用程序,应该有一个“安装”的过程,向用户询问“你要安装在哪里”,那么用户的答案放在哪里了?我的程序又去哪里获取这个答案呢?
我最后的答案是环境变量,installer把答案存到环境变量中,程序从环境变量读取答案。
这其实有点类似计算机操作系统的boot,程序的启动要从一个固定的地方开始执行,从一个固定的地方读取配置,来驱动整个程序开始运行。
环境变量在这个问题中如此好用,就是因为它是全局的,固定在电脑的一个地方,你只要调用<stdlib.h>的getenv函数就能访问。
这种便利性可以轻便地驱动一个程序的配置,比如lua.exe,你可以把它拷贝到任何位置直接运行,也就是所谓的“免安装”。
lua.exe定义了两个环境变量:
- 一个是init.lua的路径,意思是你可以指定一个boot脚本,解释器启动时先执行这个脚本进行全局初始化
- 一个是require查找lua脚本的搜索路径列表
lua源码中读取环境变量相关的代码
再说两句
- Unity的PlayerPref类在Windows上其实就是用的Windows注册表存储数据的
- 在环境变量和注册表的内容中,建议使用全英文(也就是ascii编码,而不是unicode编码),我看到的大部分都是全英文的
ini配置文件
- ini是一种数据文件格式,而且是注册表对应的数据格式
- 它的特点是扁平化和简单化,特别适合作为程序的全局配置格式
- 很多应用程序会用它作为基本的配置
比如饥荒的C:UserszoloypzuoDocumentsKleiDoNotStarvesettings.ini
[graphics]
dynamic_loading_level = 0
window_x = 399
window_y = 568
windowed_width = 1527
windowed_height = 802
[STEAM]
DISABLECLOUD = false
[MISC]
ENABLECONSOLE = true
FIRST_TIME_INSTALL = false
autocompiler_enabled = true
MOTD_IMG = 26
- 可以看到,ini格式主要是一列属性值
- 除此之外,它有分区(section)的概念,相当于一层嵌套
- 和json简单对比可以发现,这种格式没有递归嵌套,没有数组
- 因此它很容易理解,很容易解析,而且它的格式比较自由,你可以很容易对它的语法加料,稍后就可以看到,注册表如何向ini格式的语法添加类型信息
环境变量
- 环境变量是注册表的一部分,结构更加简单,因此我们先讲环境变量,再讲注册表
- 环境变量的窗口在Windows里打开是这样的
- 结构其实很简单,就是字符串映射到字符串
- 用户变量和系统变量的概念是这样的
- Windows操作系统支持多个用户,因此有一个额外的“系统用户”作为“全用户通用”的概念
- 在Windows上安装应用程序的时候,有的installer会问你是“只为当前用户安装”还是“为所有用户安装”就是指这个概念
- 搜索环境变量时,会先找当前用户的表,找不到则fallback到系统的表
- 这个概念问题不大
注册表
- 注册表在环境变量的基础上形成了一个,目录树的结构
- Windows操作系统本身把注册表作为配置机制,几乎所有的操作背后都要访问注册表,所以
- 注册表如果被损坏,你的电脑很可能就坏了,作为过来人,建议重装新电脑时备份一份
- 你可以通过修改注册表来改变Windows的行为
- 比如此电脑下面有个快捷目录“3D对象”很讨厌,我不想要它,其实找到对应注册表项目把这一条删掉重启电脑,重新加载注册表,就可以让它消失
- 注册表的窗口在Windows里打开是这样的
- 选择任意一个节点右键可以导出子树为reg文件,其实是ini格式
- 看一下对应规则
- 它把目录路径记录在方括号里,支持空格,使用反斜杠分隔
- 变量用键值对表示,类型和值用冒号分开,估计是先作为字符串读取,进一步解析得到值得
[About the Registry - Win32 apps | Microsoft Docs](https://docs.microsoft.com/en-us/windows/win32/sysinfo/about-the-registry)
[About the Windows Registry: Core Services | Microsoft Docs](https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc786735(v=ws.10))