每个进程都有一个与它关联的环境块(environment block),这是在进程地址空间内分配的一块内存,其中包含字符串类似于:
=::=::\...
VarName=VarValue\0...
\0
除第一个=::=::\外,块中可能还有其他字符串是以等号开头的,这种字符串不作为环境变量使用。
访问环境块的两种方式:
1)调用GetEnvironmentStrings获取完整的环境块
2)CUI程序专用,通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现
2.调用GetEnvironmentStrings获取完整的环境块
void DumpEnvStrings()
{
PTSTR pEnvBlock = GetEnvironmentStrings();
TCHAR szName[MAX_PATH];
TCHAR szValue[MAX_PATH];
PTSTR pszCurrent = pEnvBlock;
HRESULT hr = S_OK;
PCTSTR pszPos = NULL;
int current = 0;
while (pszCurrent != NULL)
{
// 去除无意义的串(以'='开头,如"=::=::\","=C:=C:Windows\System32")
if (*pszCurrent != TEXT('='))
{
// 查找'=',然后指针指向'='后一个字符,即值的第一个字符
pszPos = _tcschr(pszCurrent, TEXT('='));
pszPos++;
// 将变量名拷贝到szName
size_t cbNameLength = (size_t)pszPos - (size_t)pszCurrent - sizeof(TCHAR);
hr = StringCbCopyN(szName, MAX_PATH, pszCurrent, cbNameLength);
if (FAILED(hr)) {
break;
}
// 获取值
hr = StringCbCopyN(szValue, MAX_PATH, pszPos, _tcslen(pszPos)+1);
if (SUCCEEDED(hr)) {
_tprintf(TEXT("[%u] %s=%s\r\n"), current, szName, szValue);
}
else if (hr == STRSAFE_E_INSUFFICIENT_BUFFER){
// 发生错误,检查截断
_tprintf(TEXT("[%u] %s=%s...\r\n"), current, szName, szValue);
}
else {
// 这里应该不能发生
_tprintf(TEXT("[%u] %s=???\r\n"), current, szName);
break;
}
}
else {
_tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);
}
current++;
// 指针移动到字符串末尾
while (*pszCurrent != TEXT('\0'))
pszCurrent++;
pszCurrent++;
// 是否是最后一个字符串
if (*pszCurrent == TEXT('\0'))
break;
}
// 释放内存
FreeEnvironmentStrings(pEnvBlock);
}

3.通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现
void DumpEnvVariables(PTSTR pEnvBlock[])
{
int current = 0;
PTSTR* pElement = (PTSTR*)pEnvBlock;
PTSTR pCurrent = NULL;
while (pElement != NULL)
{
pCurrent = (PTSTR)(*pElement);
if (pCurrent == NULL)
{
// 没有更多环境变量了
pElement = NULL;
}
else
{
_tprintf(TEXT("[%u] %s\r\n"), current, pCurrent);
current++;
pElement++;
}
}
}
int _tmain()
{
DumpEnvVariables(_wenviron);
return 0;
}

本文链接:https://it72.com:4443/11334.htm