[英]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)
構造key
和value
,如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.