Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set environment variable for use with getenv (not GetEnvironmentVariable)

I have a DLL obtaining startup options using getenv (<stdlib.h>) call. I would like to set that variable in the same process, before opening the DLL, so that it is accessible via getenv. Which function should I use to set it?

I learned that there are two sets of env vars under windows: one is manipulated via win32 API (GetEnvironemntVariable, SetEnvironmentVariable), another one can be read using getenv, and probably set via _putenv, is that the one I should use?

Is this function accessible from python, perhaps via ctypes?

like image 261
eudoxos Avatar asked Sep 24 '26 23:09

eudoxos


1 Answers

The current ~VS2019 situation appears to be:

  • The calls to the getenv function retrieve the values from a block the MS CRT initializes at load time.
  • Calls to GetEnvironmentVariable retrieve the value from the process environment block.
  • Calls to SetEnvironmentVariable update only the value from the process environment block. These changes will not be seen by getenv.
  • Calls to putenv update both the value in the CRT block and also additionally call Win32 SetEnvironmentVariable to update the process environment block.

So, actually regardless of what you use it for:

  • Use _wputenv_s to set the env var - it will update both.
  • Use ::GetEnvironmentVariableW to read: It will read from the environment block, which will contain the value regardless of which method was used.

Regarding getenv

If the code using getenv is using the same MS CRT that your code -- that is, the code is dynamically linked to the CRT and actually uses the same version as you, then you can always use putenv.

If the DLL (AND its CRT) is dynamically or delay-loaded and you are able to call putenv before the dll is loaded, then you can use it.

(This is conjecture, I have not tested this exactly:) If the DLL is already loaded in you process and it uses a statically linked CRT, or another CRT than the one you are using, than the environment data for its getenv call is already loaded up, an nothing that you do on your side of the DLL boundary will change that. Out of luck in this case I guess.

Ref:

  • https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/getenv-wgetenv?view=msvc-170
  • https://github.com/curl/curl/issues/4774
  • https://blogs.msmvps.com/senthil/2009/10/13/when-what-you-set-is-not-what-you-get-setenvironmentvariable-and-getenv/
like image 94
Martin Ba Avatar answered Sep 27 '26 11:09

Martin Ba