什么是系统环境变量

每台计算机针对当前用户和系统中所有用户分别提供了两个环境变量设置,通过计算机属性>环境变量的界面,我们可以查看当前这台计算机上的所有环境变量,这些环境变量都是key-value键值对。具体如下:

上面看到的环境变量其实是存储在注册表中的,

系统环境变量存储在计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment路径下,

用户环境变量存储在计算机\HKEY_CURRENT_USER\Environment路径下

如下两张图分别是注册表中环境变量的值:

什么是进程环境变量

我们知道,进程本质上就是一块很大的地址空间。这个地址空间分为很多个内存区。包含代码区、DLL程序集代码区、全局变量区域、线程堆栈区等。那么进程环境变量(注意这个和上面提到的系统环境变量不同)本质上也是分配在进程内存空间上的一个字符串。这个字符串的格式如下:

=::=::\0Var1=Value1\0 Var2=Value2\0 Var3=Value3\0 ... VarN=ValueN\0\0

字符串中每个环境变量的格式为key=value,变量之间用\0区分。同时环境变量字符串必须以两个\0结束。也就是以\0\0结尾。注意:对于环境变量开始的=::=::\我们可以忽略,以=号开头的所有环节变量都会被忽略掉。

默认情况下,当进程启动的时候,会将系统环境变量加载到进程的环境变量中,我们可以使用ProcessExplorer这个工具查看进程的环境变量。我们运行下面这个简单的C++控制台程序,然后打开ProcessExplorer工具找到指定进程,然后右键Properties查看属性,选中Environment这一列,就可以看到系统环境变量都被加载到了进程的环境变量中。

#include <iostream>
#include <Windows.h>
int main()
{
while (true) {
Sleep(1000);
}
return 0;
}

从上图可以很明显看到系统环境变量都被加载到了进程环境变量,同时这里有几个点需要我们注意:

1、用户变量和系统变量如果名称一致的时候,会以用户变量为准(Path变量除外),比如说,我们看到用户变量和系统变量中都有TEMP这个环境变量,并且它们的值是不同的,在用户变量中取值为:C:\Users\caoruipeng\AppData\Local\Temp,但是在系统变量中取值为:C:\Users\caoruipeng\AppData\Local\Temp,在最终的进程环境变量中,我们可以很明显看到TEMP的值为C:\Users\caoruipeng\AppData\Local\Temp。具体如下图:

2、Path这个环境变量比较特殊,用户变量和系统变量中都有这个变量,但是程序不会按照上面的规则直接以用户变量中的变量值为准。而是将两个变量的变量值合并在一起作为最终的环境变量值,不同路径之间用分号区分。具体我们可以自己查看。

3、当我们新增了用户变量和环境变量之后,一般需要重启机器或者注销重启才能使环境变量生效,这也是为什么有时候我们新增了环境变量,但是在程序中并没有读取到那个环境变量的原因。

4、进程环境变量只是系统环境变量的副本,对进程环境变量的修改并不会影响到系统环境变量。除非用户通过GUI手动修改系统环境变量。

访问进程环境变量

程序可以通过GetEnvironmentVariable 和SetEnvironmentVariable获取或者设置环境变量的值。注意:SetEnvironmentVariable函数只会修改当前进程的环境变量,而不会修改系统环境变量或其他进程的环境变量。也就是说,使用 SetEnvironmentVariable 设置的环境变量只在当前进程及其子进程中有效。

下面的代码,我们获取到环境变量OneDrive的值,然后修改这个环境变量的值,并重新打印出来。

#include <iostream>
#include <Windows.h> int main()
{
// 定义环境变量名
LPCWSTR envVarName = L"OneDrive"; // 分配缓冲区,接受环境变量值
std::wstring envVarValue(1024, L'\0'); // 获取环境变量值的长度
DWORD bufferSize = GetEnvironmentVariable(envVarName, &envVarValue[0], 1024); // 输出环境变量值
std::wcout << envVarName << L" = " << envVarValue << std::endl; // 修改环境变量的值
LPCWSTR newEnvVarValue = L"NewValue";
if (SetEnvironmentVariable(envVarName, newEnvVarValue) == 0) {
std::cerr << "Failed to set environment variable." << std::endl;
return 1;
} // 再次获取并输出修改后的环境变量值
envVarValue.assign(1024, L'\0');
bufferSize = GetEnvironmentVariable(envVarName, &envVarValue[0], 1024);
std::wcout << envVarName << L" = " << envVarValue << std::endl; return 0;
}

调试程序之后,执行结果如下:可以看到,正确的输出了环境变量OneDrive的值为C:\Users\caoruipeng\OneDrive。

重置环境变量

上面我们提到,进程启动的时候,会将系统环境变量全部加载到了内存中,如果我们不需要这些系统环境变量的话。可以通过SetEnvironmentStrings可以设置当前进程的环境变量块,通过GetEnvironmentStrings可以获取我们设置的环境变量块,当然通过GetEnvironmentVariable也可以获取到指定环境变量的值,下面我们用代码来演示一下:

#include <iostream>
#include <Windows.h>
int main()
{
// 定义新的环境块
LPCWSTR newEnvStrings = L"VAR1=Value1\0VAR2=Value2\0\0";
// 设置新的环境块
SetEnvironmentStringsW((LPWCH)newEnvStrings);
while (true) {
Sleep(1000);
}
return 0;
}

运行控制台程序之后,我们重新在ProcessExplorer中查看进程的环境变量,就会发现进程的环境变量只剩下两个VAR1和VAR2,和我们程序中设置的一样。请看下图:

下面的代码我们首先设置整个进程的环境变量块,然后通过GetEnvironmentStrings获取整个环境变量块,并且输出:

#include <iostream>
#include <Windows.h> int main()
{
// 定义新的环境块
LPCWSTR newEnvStrings = L"VAR1=Value1\0VAR2=Value2\0\0";
// 设置新的环境块
SetEnvironmentStringsW((LPWCH)newEnvStrings);
// 获取当前进程的环境块
LPWCH envStrings = GetEnvironmentStringsW();
// 遍历并输出所有环境变量
LPWCH current = envStrings;
while (*current) {
std::wcout << current << std::endl;
current += wcslen(current) + 1;
} // 定义环境变量名
LPCWSTR envVarName = L"VAR1";
// 分配缓冲区,接受环境变量值
std::wstring envVarValue(1024, L'\0');
// 获取环境变量值的长度
DWORD bufferSize = GetEnvironmentVariable(envVarName, &envVarValue[0], 1024);
std::wcout << envVarName << L" = " << envVarValue << std::endl; // 释放环境块
FreeEnvironmentStringsW(envStrings);
return 0;
}

调试程序之后,执行结果如下:可以看到GetEnvironmentVariable可以成功获取到VAR1的环境变量值

Windows编程----进程:环境变量的更多相关文章

  1. Windows 下java环境变量的配置(Windows7 ,8,8.1,10)

    Windows 下java环境变量的配置 在“系统”面板的左上角选择“高级系统设置”,在弹出的系统属性中选择”高级“项,然后点击右下角的“环境变量(N)...”,就此进入JAVA环境变量的配置. 如果 ...

  2. 在Windows下设置环境变量 运行mysql程序变得更容易

    在Windows下设置环境变量,点开始菜单,右键单击我的电脑--属性--高级--环境变量 可以看到PATH的变量是这样的: C:\WINDOWS;C:\WINDOWS\COMMAND   为了让运行m ...

  3. Linux和Windows下查看环境变量方法对比

    摘自:Linux和Windows下查看环境变量方法对比 一.查看所有环境变量的名称和值 Linux下:export Windows下:set 二.根据名称查该环境变量的值 Linux下:echo $环 ...

  4. linux和windows中设置环境变量经常使用命令

    Linux和Windows下查看环境变量方法 一.查看全部环境变量的名称和值: Linux下:export Windows下:set 二.依据名称查该环境变量的值: Linux下:echo $环境变量 ...

  5. Linux学习——shell编程之环境变量配置文件

    小白学习,在学习中总结! shell编程之环境变量配置文件 一:环境变量配置文件 1 shell编程之环境变量配置 变量类型: 用户自定义变量(本地变量) 环境变量 :定义每个用户的操作环境,如pat ...

  6. Windows系统中环境变量不展开的问题

    Windows系统中环境变量不展开的问题 问题现象:Windows.System32等系统目录里命令,无法通过Path搜索路径来执行.查看Path环境变量结果如下: D:\>echo %Path ...

  7. windows配置jdk环境变量、mysql环境变量、tomcat环境变量、maven环境变量、git环境变量、node环境变量

    一.windows配置各种环境变量后 path 路径下的目录: 二.windows 配置各种环境变量的目的: 为windows系统添加上各种环境对应的命令 举例,为什么要添加jdk的bin目录,是因为 ...

  8. UNIX环境编程学习笔记(16)——进程管理之进程环境变量

    lienhua342014-10-03 1 环境表和环境指针 在每个进程启动时,都会接到一张环境表.环境表是一个字符指针数组,其中每个指针包含一个以 null 结束的 C 字符串的地址.全局变量env ...

  9. windows编程 进程的创建销毁和分析

    Windows程序设计:进程 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,在Windows编程环境下,主要由两大元素组成: • 一个是操作系统用来管理进程的内核对象.操作系统使用内 ...

  10. Node.js-安装配置【1】-在Windows XP系统配置环境变量

    家里有台老古董台式机,安装的是Windows XP系统,摸索了一下,成功的在上面安装配置好了Node.js V4.4.7 一.安装Node.js(过程略) 二.npm配置全局和缓存路径(过程略) 三. ...

随机推荐

  1. x509.MarshalSm2PrivateKey

    根据搜索结果,x509.MarshalSm2PrivateKey 函数需要两个参数:一个 *sm2.PrivateKey 和一个 []byte 类型的密码.以下是使用 x509.MarshalSm2P ...

  2. arch 音频处显示没有输入或输出设备

    我的设备是 Dell G15 5511, 属于比较新的设备, 查看了 Fourm 与 wiki 后使用 1 yay -S sof-firmware   安装框架之后重启即可使用.

  3. Spring Validation 校验

    概述 在 Web 应用中,客户端提交数据之前都会进行数据的校验,比如用户注册时填写的邮箱地址是否符合规范.用户名长度的限制等等,不过这并不意味着服务端的代码可以免去数据验证的工作,用户也可能使用 HT ...

  4. [转]火狐浏览器访问github提示:未连接:有潜在的安全问题...github.com 启用了被称为 HTTP 严格传输安全(HSTS)的安全策略,Firefox 只能与其建立安全连接。

    火狐浏览器访问github,提示:        未连接:有潜在的安全问题:        Firefox 检测到潜在的安全威胁,并因 github.com 要求安全连接而没有继续.如果这种情况是因为 ...

  5. 微信小游戏直播在Android端的跨进程渲染推流实践

    本文由微信开发团队工程师"virwu"分享. 1.引言 近期,微信小游戏支持了视频号一键开播,将微信升级到最新版本,打开腾讯系小游戏(如跳一跳.欢乐斗地主等),在右上角菜单就可以看 ...

  6. MySQL 中information_schema、mysql、performance_schema、sys 简介

    一.information_schema简介在MySQL中,把 information_schema 看作是一个数据库,确切说是信息数据库.其中保存着关于MySQL服务器所维护的所有其他数据库的信息. ...

  7. biancheng-NumPy教程

    目录http://c.biancheng.net/numpy/ 1NumPy是什么2NumPy下载与安装3NumPy ndarray对象4NumPy数据类型5NumPy数组属性6Numpy创建数组7N ...

  8. 项目PMP之十项目沟通管理

    项目PMP之十--项目沟通管理   一.定义:通过正式或非正式途径信息有效交换获取想法.指示或情绪:向大家说明项目进度现状(即工作绩效报告) 成功的沟通:适合的沟通策略:信息传递需要恰当:理解正确:筛 ...

  9. G1原理—7.G1的GC日志分析解读

    大纲 1.TLAB的GC日志解读 2.YGC的GC日志解读 3.模拟YGC(单次GC及多次GC的不同场景) 4.打开实验选项查看YGC的详情日志信息 5.Mixed GC日志信息之初始标记过程 6.M ...

  10. Python生成成绩报告单:从理论到实践

    在教育信息化日益普及的今天,自动化生成和处理学生成绩报告单已成为学校和教育机构的一项重要任务.Python作为一种功能强大且易于学习的编程语言,非常适合用于这种数据处理和报告生成任务.本文将详细介绍如 ...