簡體   English   中英

獲取 Windows 上 C\C++ 中的所有環境變量

[英]Get all env variables in C\C++ on Windows

C\C++ 中 main 函數的簽名可以包含 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('\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.

我不知道 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 的出色回答,有兩個主要區別:

  • 使用wchar_t而不是TCHAR 沒有人應該在 Windows 中使用非寬字符。
  • 使用std::wstring str(buffer, buflen)構造keyvalue ,如this answer中所建議。 我相信性能應該比逐個字符連接更好,盡管我沒有測量它。

代碼:

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;
}

這是 Konrad 和 Jonathan 在這個問題中現有答案的一個變體,它可能會幫助任何想要創建單個 Widechar 字符串以記錄到文件或(在我的情況下)進行遠程診斷的人。 請隨意給他們投票。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM