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

时间:2012-03-02 14:42:06

标签: c++ c environment-variables

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

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

第三个是环境变量。

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

3 个答案:

答案 0 :(得分:6)

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

该块是一个连续的C风格字符串,包含以空值终止的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('\0'); ++i) {
        tstring key;
        tstring value;

        for (; *i != T('='); ++i)
            key += *i;
        ++i;
        for (; *i != T('\0'); ++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.

答案 1 :(得分:4)

我不知道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);

}

答案 2 :(得分:1)

以下内容基于@Konrad's excellent answer,主要有两点不同:

  • 使用key而不是value。没有人应该在Windows中使用非宽字符。
  • this answer中的建议,使用std::wstring str(buffer, buflen)构建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'\0'; ) { 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; } 和{{1}}。我认为性能应该比使用char-by-char更好,尽管我还没有测量过它。

代码:

{{1}}