在Windows上获取C:C++中的所有env变量
Get all env variables in CC++ on Windows
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)
构建key
和value
。我认为性能应该比一个字符接一个字符地连接要好,尽管我还没有衡量过
代码:
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);
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 将成员变量添加到共享库中的类中,不会破坏二进制兼容性吗
- 将数组的地址分配给变量并删除
- 为"adjacent"变量赋值时出现问题
- enum是C++中的宏变量还是整数变量
- 在全局变量中保存类的实例以重新创建类(创建"backup")
- 用C++中的一个变量定义一个常量
- 具有奇怪重复模板模式的派生类中的成员变量已损坏
- 你能重载对象变量名本身返回的内容吗
- 内置函数可查看CPP中的成员变量
- 是否可以初始化不可复制类型的成员变量(或基类)
- 尝试通过多个向量访问变量时,向量下标超出范围
- 试图让变量检查数组中的某些内容
- Cpp-Tuple使用带有变量的get
- 将包含C样式数组的对象初始化为成员变量(C++)
- 当vector是tje全局变量时,c++中vector的内存管理
- 通过多个头文件使用常量变量
- std::threads可以从Windows DLL中的全局变量创建/销毁吗?
- Windows SDK 8:关于安装位置,文件夹命名法和Windowssdkdir_old Env变量的混乱
- 在Windows上获取C:C++中的所有env变量