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 = 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 = ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), NULL, 0);
    PTSTR buffer = new TCHAR[chValue];

    chValue = ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), buffer, chValue);

    delete[] buffer;

由于我们不知道需要多少个字符来保持一个环境变量的值,所以第一次参数3传入0,它会返回所需要字符的数量。

5.为当前进程设置指定环境变量的内容。

BOOL SetEnvironmentVariableW(
  [in]           LPCWSTR lpName,
  [in, optional] LPCWSTR lpValue
);

这个函数可以添加变量、删除变量、修改变量。

  • lpName存在,就修改
  • lpName不存在,就添加
  • lpValue传NULL,就删除

猜你喜欢

转载自blog.csdn.net/wzz953200463/article/details/126273826
今日推荐