在Windows上获取C:C++中的所有env变量

Get all env variables in CC++ on Windows

本文关键字:env 变量 C++ Windows 获取      更新时间:2023-10-16

C:\C++中主函数的签名可以包括3个参数:

main( int argc, char *argv[ ], char *envp[ ] )

三是环境变量。

我正在VS10下编译一个库,因此我没有main()。如何获得与char *envp[]中完全相同类型的环境变量?我宁愿不使用.NET来减少依赖性,也许有一天我会对可移植性持开放态度。

GetEnvironmentStrings返回一个(只读!)指针,指向进程的环境块的开头。

该块是一个连续的C样式字符串,包含以null结尾的key=value对。该块以一个额外的空终止结束。

为了更方便地访问,请使用以下功能:

typedef std::basic_string<TCHAR> tstring; // Generally convenient
typedef std::map<tstring, tstring> environment_t;
environment_t get_env() {
    environment_t env;
    auto free = [](LPTCH p) { FreeEnvironmentStrings(p); };
    auto env_block = std::unique_ptr<TCHAR, decltype(free)>{
            GetEnvironmentStrings(), free};
    for (LPTCH i = env_block.get(); *i != T(''); ++i) {
        tstring key;
        tstring value;
        for (; *i != T('='); ++i)
            key += *i;
        ++i;
        for (; *i != T(''); ++i)
            value += *i;
        env[key] = value;
    }
    return env;
}

当然,一个合适的实现会将其封装在一个类中,并且可能使用std::stringstream,而不是手动迭代字符,一次连接char上的字符串。但是我很懒。

用法如下:

environment_t env = get_env();
// Now you can write env[T("Var1")] to access a variable.

我不知道windows,但在Linux上,这个变量:

extern char **environ;

正是你想要的。

#include <stdio.h>
#include <assert.h>
extern char **environ;
int main (int ac, char **av, char **envp) {
  assert(envp == environ);
}

以下是基于@Konrad的出色回答,有两个主要区别:

  • 使用CCD_ 7而不是CCD_。任何人都不应该在Windows中使用非宽字符
  • 使用std::wstring str(buffer, buflen)构建keyvalue。我认为性能应该比一个字符接一个字符地连接要好,尽管我还没有衡量过

代码:

typedef std::map<std::wstring, std::wstring> environment_t;
environment_t get_env() {
    environment_t env;
    auto free = [](wchar_t* p) { FreeEnvironmentStrings(p); };
    auto env_block = std::unique_ptr<wchar_t, decltype(free)>{
        GetEnvironmentStringsW(), free};
    for (const wchar_t* name = env_block.get(); *name != L''; )
    {
        const wchar_t* equal = wcschr(name, L'=');
        std::wstring key(name, equal - name);
        const wchar_t* pValue = equal + 1;
        std::wstring value(pValue);
        env[key] = value;
        name = pValue + value.length() + 1;
    }
    return env;
}

这是Konrad和Jonathan在这个问题中现有答案的变体,可能有助于任何想要创建一个宽字符字符串用于记录到文件或(在我的情况下)用于远程诊断的人。请随意投票支持他们。

LPWCH we = GetEnvironmentStrings();
const wchar_t* w = we;
do {
    eline = w;
    w += eline.length() + 1;
    env += eline;
    env += L"rn";
} while ((eline.length() > 0) && (*w != L''));
FreeEnvironmentStrings(we);