c获取当前程序的路径_程序的安装配置,Windows注册表,环境变量和ini配置文件

b2c302a20041cf44b833796598ba7948.png

目录

  • ini配置文件
  • 环境变量
  • 注册表

缘起

我在写引擎的时候遇到一个问题,就是我的引擎有一些配置文件放在一些地方,程序怎么知道它们放在哪里呢?

我当然可以在程序里硬编码一个路径,但是如果别人拷贝了我的引擎,放在了他自己喜欢的地方,那么我在程序里硬编码的路径当然是错误的。

所以我的引擎作为一个应用程序,应该有一个“安装”的过程,向用户询问“你要安装在哪里”,那么用户的答案放在哪里了?我的程序又去哪里获取这个答案呢?

我最后的答案是环境变量,installer把答案存到环境变量中,程序从环境变量读取答案。

这其实有点类似计算机操作系统的boot,程序的启动要从一个固定的地方开始执行,从一个固定的地方读取配置,来驱动整个程序开始运行。


环境变量在这个问题中如此好用,就是因为它是全局的,固定在电脑的一个地方,你只要调用<stdlib.h>的getenv函数就能访问。

这种便利性可以轻便地驱动一个程序的配置,比如lua.exe,你可以把它拷贝到任何位置直接运行,也就是所谓的“免安装”。

lua.exe定义了两个环境变量:

  • 一个是init.lua的路径,意思是你可以指定一个boot脚本,解释器启动时先执行这个脚本进行全局初始化
  • 一个是require查找lua脚本的搜索路径列表

lua源码中读取环境变量相关的代码

d19be9c221aaf3445d23d324789f1bc1.png

再说两句

  • 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里打开是这样的

6e3b61386289f75de06c6045a7ca064b.png
  • 结构其实很简单,就是字符串映射到字符串
  • 用户变量和系统变量的概念是这样的
    • Windows操作系统支持多个用户,因此有一个额外的“系统用户”作为“全用户通用”的概念
    • 在Windows上安装应用程序的时候,有的installer会问你是“只为当前用户安装”还是“为所有用户安装”就是指这个概念
    • 搜索环境变量时,会先找当前用户的表,找不到则fallback到系统的表
    • 这个概念问题不大

注册表

  • 注册表在环境变量的基础上形成了一个,目录树的结构
  • Windows操作系统本身把注册表作为配置机制,几乎所有的操作背后都要访问注册表,所以
    • 注册表如果被损坏,你的电脑很可能就坏了,作为过来人,建议重装新电脑时备份一份
    • 你可以通过修改注册表来改变Windows的行为
      • 比如此电脑下面有个快捷目录“3D对象”很讨厌,我不想要它,其实找到对应注册表项目把这一条删掉重启电脑,重新加载注册表,就可以让它消失

v2-fa5db10be4f80009b03a28caa025e6fc_b.jpg
  • 注册表的窗口在Windows里打开是这样的

7bc0cb564033fc714a9fc95da4762886.png
  • 选择任意一个节点右键可以导出子树为reg文件,其实是ini格式
    • 看一下对应规则
    • 它把目录路径记录在方括号里,支持空格,使用反斜杠分隔
    • 变量用键值对表示,类型和值用冒号分开,估计是先作为字符串读取,进一步解析得到值得

493f82522c8e75d1fef8fac5b2e8e255.png

[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))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值