天天看点

Windows核心编程学习五:进程的环境变量1.进程的环境变量2.调用GetEnvironmentStrings获取完整的环境块3.通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现

注:源码为学习《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);
}
           
Windows核心编程学习五:进程的环境变量1.进程的环境变量2.调用GetEnvironmentStrings获取完整的环境块3.通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现

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);
}
           
Windows核心编程学习五:进程的环境变量1.进程的环境变量2.调用GetEnvironmentStrings获取完整的环境块3.通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现

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;
}
           
Windows核心编程学习五:进程的环境变量1.进程的环境变量2.调用GetEnvironmentStrings获取完整的环境块3.通过应用程序main入口点函数所接收的TCHAR* env[]参数来实现

继续阅读