• Windows提取环境变量


    1.简介

    每个进程都有一个与它关联的环境块,这是在进程地址空间内分配的一块内存。

    每个字符串的第一部分是一个环境变量的名称,后跟一个等号,等号之后是希望赋给此变量的值,注意:除了第一个=::=::\字符串,块中可能还有其他字符串是以(=)开头的。这种字符串不能作为环境变量的使用。

    调用GetEnvironmentStrings函数来获取完整的环境块。

    2.提取环境变量

    1. PTSTR env = GetEnvironmentStrings();
    2. TCHAR key[MAX_PATH];
    3. TCHAR value[MAX_PATH];
    4. PTSTR cur = env;
    5. HRESULT hr = S_OK;
    6. PCTSTR pszPos = NULL;
    7. int current = 0;
    8. while (cur != NULL)
    9. {
    10. if (*cur != TEXT('='))
    11. {
    12. pszPos = _tcschr(cur, TEXT('='));
    13. pszPos++;
    14. size_t cbNameLength = (size_t)pszPos - (size_t)cur - sizeof(TCHAR);
    15. hr = StringCbCopyN(key, MAX_PATH, cur, cbNameLength);
    16. if (FAILED(hr))
    17. {
    18. break;
    19. }
    20. hr = StringCchCopyN(value, MAX_PATH, pszPos, _tcslen(pszPos) + 1);
    21. if (SUCCEEDED(hr))
    22. {
    23. _tprintf(TEXT("[%u] %s=%s\r\n"), current, key, value);
    24. }
    25. else
    26. {
    27. if (hr == STRSAFE_E_INSUFFICIENT_BUFFER)
    28. {
    29. _tprintf(TEXT("[%u] %s=%...s\r\n"), current, key, value);
    30. }
    31. else
    32. {
    33. _tprintf(TEXT("[%u] %s=???\r\n"), current, key);
    34. break;
    35. }
    36. }
    37. }
    38. else
    39. {
    40. _tprintf(TEXT("[%u] %s\r\n"), current, cur);
    41. }
    42. current++;
    43. while (*cur != TEXT('\0'))
    44. cur++;
    45. cur++;
    46. if (*cur == TEXT('\0'))
    47. break;
    48. }

    以=开头的无效字符串会被跳过。其他每个有效的字符串会被逐一解析。‘=’字符被用作名称与值之间的分隔符。

    如果不再需要GetEnvironmentStrings函数返回的内存块,应调用FreeEnvironmentStrings释放。

    3.判断一个环境变量是否存在

    1. DWORD dwResult = GetEnvironmentVariableW(
    2. _In_opt_ LPCWSTR lpName,
    3. _Out_writes_to_opt_(nSize,return + 1) LPWSTR lpBuffer,
    4. _In_ DWORD nSize
    5. );

    参数1:指向查找的变量名称。

    参数2:指向保持变量值的缓冲区。

    参数3:指出缓冲区的大小(字符数)。

    如果找到变量名,此函数返回复制到缓冲区的字符数;如果没有找到就返回0。

    示例:

    1. void PrintEnvironmentVariable(PCTSTR name)
    2. {
    3. PTSTR value = NULL;
    4. DWORD dwResult = GetEnvironmentVariable(name, value, 0);
    5. if (dwResult)
    6. {
    7. DWORD size = dwResult * sizeof(TCHAR);
    8. value = (PTSTR)malloc(size);
    9. GetEnvironmentVariable(name, value, size);
    10. _tprintf(TEXT("%s=%...s\r\n"), name, value);
    11. free(value);
    12. }
    13. else
    14. {
    15. _tprintf(TEXT("%s unknown\r\n"), name);
    16. }
    17. }

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

    4.可替换的字符串

    在许多字符串的内部,都包含了“可替换的字符串”。例:

    %USERPROFILE%\Documents

    两个%中间的就是“可替换的字符串”,不同的机器上,值会不一样,比如我的就是C:\Users\wzz\Documents。

    Windows提供了ExpandEnvironmentStrings函数来解析。函数原型如下:

    1. ExpandEnvironmentStringsW(
    2. _In_ LPCWSTR lpSrc,
    3. _Out_writes_to_opt_(nSize,return) LPWSTR lpDst,
    4. _In_ DWORD nSize
    5. );

    参数1:一个包含一个或多个环境变量字符串的缓冲区,格式为:    %variableName%   

    参数2:一个指向缓冲区的指针,用于接收在lpSrc缓冲区中展开环境变量字符串的结果。

    参数3:lpDst参数所指向的缓冲区中可以存储的最大字符数。示例:

    1. DWORD chValue = ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), NULL, 0);
    2. PTSTR buffer = new TCHAR[chValue];
    3. chValue = ExpandEnvironmentStrings(TEXT("%USERPROFILE%"), buffer, chValue);
    4. delete[] buffer;

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

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

    1. BOOL SetEnvironmentVariableW(
    2. [in] LPCWSTR lpName,
    3. [in, optional] LPCWSTR lpValue
    4. );

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

    • lpName存在,就修改
    • lpName不存在,就添加
    • lpValue传NULL,就删除
  • 相关阅读:
    对Docker的认识和总结
    Java异常
    「刷起来」Go必看的进阶面试题详解
    叮咚外卖小程序6.4.3+超级跑腿2.0.3+前端完美运营版【未编译前端+教程】
    【Verilog基础】8.加法器
    ModelSim相关实用设置
    ​Spring Framework(Spring 框架):IOC、DI 和 AOP
    基于JavaScript开发的网页多点绘图程序
    小白整理了VUEX
    主流分布式存储技术对比分析:GFS、HDFS、GlusterFS、Ceph、Swift
  • 原文地址:https://blog.csdn.net/wzz953200463/article/details/126273826