JHowzer
JHowzer

Reputation: 4264

Update Environment Variable when changes made from My Computer

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

Answers (4)

JHowzer
JHowzer

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

Deanna
Deanna

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

Rocky Pulley
Rocky Pulley

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

Hans Passant
Hans Passant

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

Related Questions