#include <Windows.h>
#include <tchar.h>
#include <strsafe.h> // 使用了StringCbCopyN等安全字符串处理函数
void DumpEnvStrings()
{
// 结尾有两个'\0',一个是最后一个环境变量的结尾,另一个是整个块的结尾
PTSTR pszEnvBlock = GetEnvironmentStrings();
TCHAR szName[MAX_PATH];
TCHAR szValue[MAX_PATH];
PTSTR pszCurrent = pszEnvBlock;
HRESULT hr = S_OK;
PCTSTR pszPos = NULL;
int current = 0;
while (pszCurrent != NULL)
{
// 当地一个字母不是=的时候 (一般环境变量字符串是这个样子[0]=::=::\[1]=c:\:=c:\system32 [2]=eistcode=0x0000 [0]这种是字符串数组的第一个字符串这个意思 每个字符串都是\0结束的)
if (*pszCurrent != TEXT('='))
{
// 找到第一个等号的位置
pszPos = _tcschr(pszCurrent, TEXT('='));
if (pszPos == NULL)
{
_tprintf(TEXT("not found = \n"));
}
// 位置指针指向环境变量值的第一个位置处
pszPos++;
// 获取环境变量名(去掉等号)(此处必须强制类型转换,否则变量名不完整)
size_t cbNameLength = (size_t)pszPos - (size_t)pszCurrent - sizeof(TCHAR);
hr = StringCbCopyN(szName, MAX_PATH, pszCurrent, cbNameLength);
if (FAILED(hr))
{
break;
}
// 获取环境变量值(包括最后的NULL字符,由于是让人看见的所以允许“截断”)
hr = StringCchCopyN(szValue, MAX_PATH, pszPos, _tcslen(pszPos)+1);
if (SUCCEEDED(hr))
{
_tprintf(TEXT("(%u) %s = %s\r\n"), current, szName, szValue);
}
else // 有错误发生,
{
// 检查“截断”
if (STRSAFE_E_INSUFFICIENT_BUFFER)
{
_tprintf(TEXT("(%u) %s = %s...\r\n"), current, szName, szValue);
}
else // 不应该发生的错误
{
_tprintf(TEXT("(%u) %s = %s???\r\n"), current, szName, szValue);
}
break;
}
}
else // 首个字符是等号
{
_tprintf(TEXT("(%u) %s\r\n"), current, pszCurrent);
}
// 下一个环境变量
current++;
// 指针指向字符串结尾 排除掉第一个字符是=号的字符串
while (*pszCurrent != TEXT('\0'))
{
pszCurrent++;
}
// 指针指向下一个环境变量
pszCurrent++;
// 检查是否还有环境变量
if (*pszCurrent == TEXT('\0'))
{
break;
}
}
// 释放内存
FreeEnvironmentStrings(pszEnvBlock);
}
int main()
{
DumpEnvStrings();
return 0;
}