1.简介
每个进程都有一个与它关联的环境块,这是在进程地址空间内分配的一块内存。
每个字符串的第一部分是一个环境变量的名称,后跟一个等号,等号之后是希望赋给此变量的值,注意:除了第一个=::=::\字符串,块中可能还有其他字符串是以(=)开头的。这种字符串不能作为环境变量的使用。
调用GetEnvironmentStrings函数来获取完整的环境块。
2.提取环境变量
PTSTR env = GetEnvironmentStrings();
TCHAR key[MAX_PATH];
TCHAR value[MAX_PATH];
PTSTR cur = env;
HRESULT hr = S_OK;
PCTSTR pszPos = NULL;
int current = 0;
while (cur != NULL)
{
if (*cur != TEXT('='))
{
pszPos = _tcschr(cur, TEXT('='));
pszPos++;
size_t cbNameLength = (size_t)pszPos - (size_t)cur - sizeof(TCHAR);
hr = StringCbCopyN(key, MAX_PATH, cur, cbNameLength);
if (FAILED(hr))
{
break;
}hr = StringCchCopyN(value, MAX_PATH, pszPos, _tcslen(pszPos) + 1);
if (SUCCEEDED(hr))
{
_tprintf(TEXT("[%u] %s=%s\r\n"), current, key, value);
}
else
{
if (hr == STRSAFE_E_INSUFFICIENT_BUFFER)
{
_tprintf(TEXT("[%u] %s=%...s\r\n"), current, key, value);
}
else
{
_tprintf(TEXT("[%u] %s=???\r\n"), current, key);
break;
}
}
}
else
{
_tprintf(TEXT("[%u] %s\r\n"), current, cur);
}current++;
while (*cur != TEXT('\0'))
cur++;
cur++;
if (*cur == TEXT('\0'))
break;
}
以=开头的无效字符串会被跳过。其他每个有效的字符串会被逐一解析。‘=’字符被用作名称与值之间的分隔符。
如果不再需要GetEnvironmentStrings函数返回的内存块,应调用FreeEnvironmentStrings释放。
3.判断一个环境变量是否存在
DWORD dwResult = GetEnvironmentVariableW(
_In_opt_ LPCWSTR lpName,
_Out_writes_to_opt_(nSize,return + 1) LPWSTR lpBuffer,
_In_ DWORD nSize
);
参数1:指向查找的变量名称。
参数2:指向保持变量值的缓冲区。
参数3:指出缓冲区的大小(字符数)。
如果找到变量名,此函数返回复制到缓冲区的字符数;如果没有找到就返回0。
示例:
void PrintEnvironmentVariable(PCTSTR name)
{
PTSTR value = https://www.it610.com/article/NULL;
DWORD dwResult = GetEnvironmentVariable(name, value, 0);
if (dwResult)
{
DWORD size = dwResult * sizeof(TCHAR);
value = (PTSTR)malloc(size);
GetEnvironmentVariable(name, value, size);
_tprintf(TEXT("%s=%...s\r\n"), name, value);
free(value);
}
else
{
_tprintf(TEXT("%s unknown\r\n"), name);
}
}
由于我们不知道需要多少个字符来保持一个环境变量的值,所以第一次参数3传入0,它会返回所需要字符的数量。
4.可替换的字符串
在许多字符串的内部,都包含了“可替换的字符串”。例:
%USERPROFILE%\Documents
两个%中间的就是“可替换的字符串”,不同的机器上,值会不一样,比如我的就是C:\Users\wzz\Documents。
Windows提供了ExpandEnvironmentStrings函数来解析。函数原型如下:
ExpandEnvironmentStringsW(
_In_ LPCWSTR lpSrc,
_Out_writes_to_opt_(nSize,return) LPWSTR lpDst,
_In_ DWORD nSize
);
参数1:一个包含一个或多个环境变量字符串的缓冲区,格式为:%variableName%
参数2:一个指向缓冲区的指针,用于接收在lpSrc缓冲区中展开环境变量字符串的结果。
参数3:lpDst参数所指向的缓冲区中可以存储的最大字符数。示例:
DWORD chValue = https://www.it610.com/article/ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), NULL, 0);
PTSTR buffer = new TCHAR[chValue];
chValue = https://www.it610.com/article/ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), buffer, chValue);
delete[] buffer;
由于我们不知道需要多少个字符来保持一个环境变量的值,所以第一次参数3传入0,它会返回所需要字符的数量。
5.为当前进程设置指定环境变量的内容。
BOOL SetEnvironmentVariableW(
[in]LPCWSTR lpName,
[in, optional] LPCWSTR lpValue
);
【Windows核心编程|Windows提取环境变量】这个函数可以添加变量、删除变量、修改变量。
- lpName存在,就修改
- lpName不存在,就添加
- lpValue传NULL,就删除
推荐阅读
- Windows核心编程|Windows内核对象
- c语言|学习了循环碰到了编写计算n的阶乘的题目,由此引发了一系列问题,包括一些初学者常见的坑,以及如何简化代码
- python全栈开发|进军Python全栈开发--14.Python中的数据结构与算法
- 服务器|常见服务器操作系统有哪些
- b树|MySQL索引原理,设计原则
- 算法|KMP算法、计算器(一)、(二)
- 高质量工具|强烈推荐8个很实用的神级软件,让人相见恨晚
- JAVA|数组基本使用——java SE
- 后端|马老师力荐(腾讯 SpringBoot 高阶笔记,限时开源)