Windows核心编程|Windows提取环境变量

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,就删除

    推荐阅读