注:源碼為學習《Windows核心程式設計》的一些嘗試,非原創。若能有助于一二訪客,幸甚。
1.程序的環境變量
每個程序都有一個與它關聯的環境塊(environment block),這是在程序位址空間内配置設定的一塊記憶體,其中包含字元串類似于:
=::=::\...
VarName=VarValue\0...
\0
除第一個=::=::\外,塊中可能還有其他字元串是以等号開頭的,這種字元串不作為環境變量使用。
通路環境塊的兩種方式:
1)調用GetEnvironmentStrings擷取完整的環境塊
2)CUI程式專用,通過應用程式main入口點函數所接收的TCHAR* env[]參數來實作
2.調用GetEnvironmentStrings擷取完整的環境塊
1)不論是不是環境變量,暫且都列印出來
void DumpEnvStrings()
{
PTSTR pEnvBlock = GetEnvironmentStrings();
PTSTR pszCurrent = pEnvBlock;
int current = 0;
while (pszCurrent != NULL)
{
// 不論是不是環境變量,暫且都列印
_tprintf(TEXT("[%u] %s\r\n"), current, pszCurrent);
current++;
// 指針移動到字元串末尾
while (*pszCurrent != TEXT('\0'))
pszCurrent++;
pszCurrent++;
// 是否是最後一個字元串
if (*pszCurrent == TEXT('\0'))
break;
}
// 釋放記憶體
FreeEnvironmentStrings(pEnvBlock);
}
2)去除無意義的串
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;
}