Get all env variables in C \ C ++ on Windows

The signature for the main function in C \ C ++ can include 3 arguments:

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

The third environment variable.

I am compiling a library under VS10 and therefore I do not have main() . How can I get environment variables in the same type as in char *envp[] ? I prefer not to use .NET to reduce dependencies and maybe one day be open to portability.

+6
source share
3 answers

GetEnvironmentStrings returns a (read-only!) Pointer to the beginning of the environment block for the process.

The block is a continuous C-style string containing key=value pairs with zero completion. The block terminates with an additional null termination.

To make access more convenient, use something like the following function:

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

Of course, a proper implementation would encapsulate this into a class and probably use std::stringstream instead of manually repeating by characters, concatenating strings by char at a time. But lazy.

Usage looks like this:

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

I do not know about Windows, but on Linux this variable:

 extern char **environ; 

- exactly what you are looking for.

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

Following is @Konrad's excellent answer with two main differences:

  • Using wchar_t , not TCHAR . On Windows, no one should use narrow characters.
  • Building key and value with std::wstring str(buffer, buflen) as suggested in this answer . I believe that performance should be better than the char -by-char assignment, although I have not measured it.

the code:

 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
source

Source: https://habr.com/ru/post/909826/


All Articles