中国建设厅官方网站/国内新闻今日头条
文章目录
- 导读
- 开发环境
- 实现
- 通过procexp打开1836进程的环境变量列表
- 修改注册表(手动/编码实现)
- 广播WM_SETTINGCHANGE消息
- 再次通过procexp打开1836进程的环境变量列表
- 也可以通过《系统属性 > 环境变量》来查看是否生效
- 文章小结
- 参考资料
导读
一直都很好奇一些安装软件,如何将自己安装的路径,添加到环境变量PATH中的(之前尝试用API SetEnvironmentVariable只在当前进程有效)。今天终于查了查资料实现了该需求,并通过工具验证了该实现。
开发环境
版本号 | 描述 | |
---|---|---|
文章日期 | 2022-11-19 | |
操作系统 | Win11-22H2 | 内部版本号22621.674 |
Visual Studio 2019 | 16.11.12 | |
Windows SDK | 10.0.17763.0 | |
实现
通过procexp打开1836进程的环境变量列表
参考下面的比较图片
修改注册表(手动/编码实现)
广播WM_SETTINGCHANGE消息
编写如下代码并执行:
// 阻塞UINT fuFlags = SMTO_BLOCK;// The duration of the time-out period, in milliseconds. If the message is a broadcast message, each window can use the full time-out period. For example, if you specify a five second time-out period and there are three top-level windows that fail to process the message, you could have up to a 15 second delay.// 消息超时时间,每个顶层窗口都会等待uTimeout毫秒。UINT uTimeout = 100;DWORD dwResult = 0;LRESULT ret = ::SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)_T("Environment"), fuFlags, uTimeout, &dwResult);printf("ret, dwResult, GetLastError() = %d %d %d \n", ret, dwResult, GetLastError());
再次通过procexp打开1836进程的环境变量列表
比较执行广播消息前后的列表,发现已经新增了环境变量
FLAG_MY_PIPE_NAME
。
也可以通过《系统属性 > 环境变量》来查看是否生效
文章小结
下面两组函数只能修改
当前进程
的环境变量(子进程
默认继承修改后的环境变量)。
- getenv & setenv
- GetEnvironmentStrings & SetEnvironmentVariable
环境变量存储在注册表
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
中,系统启动后,将所有环境变量加载到explorer
等进程中(保存到PBE中),explorer
之后的进程会继承该环境变量。
如果直接修改注册表项,并不能修改已经启动进程的环境变量,需要通过广播消息
WM_SETTINGCHANGE
通知给所有已经启动的带窗口处理函数
的进程(cmd命令的进程不处理窗口消息,不能更新环境变量)。
ps: 通过三方工具修改环境变量,《Windows修改环境变量的工具—Rapid Environment Editor》https://blog.csdn.net/COCO56/article/details/102425383
参考资料
- https://learn.microsoft.com/zh-cn/windows/win32/procthread/environment-variables
- https://learn.microsoft.com/zh-cn/windows/win32/winmsg/wm-settingchange
- qq群:夜猫逐梦技术交流裙/953949723
**ps:**文章中内容仅用于技术交流,请勿用于违规违法行为。