Reputation: 4264
I have a C++ program that calls GetEnvironmentVariable()
to get the 'Path' variable information. If I am running my program, and meanwhile, I change my 'Path' variable via "MyComputer->Properties->Environment Variables"?... is it 100% impossible to retrieve the updated 'Path' variable from GetEnvironmentVariable()
without restarting my program (and Visual Studio).
In this posting, Anders K mentions:
"Make sure you restart the application before you can read the environment variable. The same happens if you have a console window open and change the environment variables on My Computer, these are not noted in any existing console windows. You need to restart them to get a copy of the new environment variables."
Does this mean that there is 100% no way to retrieve the updated "Path" variable? I am unsure if I am wasting my time or not.
Also, I attempted something like this, but was not successful.
Thank you.
Upvotes: 1
Views: 788
Reputation: 4264
From the advice of the helpful responders, I decided to use registry keys to get updated Environment Variables instead.
Assuming:
DWORD BufferSize = 16383;
TCHAR pathVar[16383];
Before, I did:
GetEnvironmentVariable(_T("Path"),pathVar,16383);
Which never gave me the updated Path environment variable, if I updated via My Computer->Properties.
Now, I do:
DWORD dwRet = RegGetValue(HKEY_LOCAL_MACHINE,
_T("SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"),
_T("Path"), RRF_RT_ANY, NULL, (PVOID)&pathVar, &BufferSize);
if(dwRet != ERROR_SUCCESS){
GetEnvironmentVariable(_T("Path"),pathVar,16383);
}
Which gets the value from the registry key. But, if for some reason RegGetValue()
fails, it will get the value via GetEnvironmentVariable()
, which may not be fully updated, but atleast I get a value that I may be able to use. Thank you everyone for your suggestions.
Upvotes: 0
Reputation: 24283
The environment variables don't come directly from the registry to your app, they are read once by Explorer then passed/inherited by any child processes it creates. There is however a mechanism that allows an application, when it changes the registry values, to tell applications to reload these values using the WM_SETTINGCHANGE
broadcast message with lParam
pointing to a string containing "Environment".
Normally, only Explorer honours this message, but you can detect it in your own application and re read the data directly from the registry.
Upvotes: 1
Reputation: 23321
If you need it to be dynamic in that sense then you are using the wrong thing. Don't use environment variables, use something like registry entries.
Upvotes: 2
Reputation: 942050
Well, not 100% impossible. Editing the environment variables like that only sets registry keys. You can see them back with Regedit.exe, navigate to HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Control\Session Manager\Environment, you'll see the list of values you saw back in the editing box. The user specific ones are stored in HKEY_CURRENT_USER\Environment.
The key then is exactly when a process starts using these values. Which depends, a process can inherit the environment from the process that started it, the lpEnvironment argument for CreateProcess() determines this. Passing a NULL and thus inheriting is very common, so the started process won't see the changes, it got a copy of the stale environment from its parent. The only way to be really sure is to log-off and log back on so you know for a fact that such a process got started with the changed environment. Or just try it so you know.
The not 100% impossible angle is to actually read these registry keys. Not exactly very practical and of course entirely un-portable. The PATH environment variable is really only useful when launching programs from a shell.
Upvotes: 3