Windows environment variables and manual registry editing – no/wrong values issue

environment-variableswindows

Open regedit.exe, navigate to HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment. Create two environment variables:

Name   Type            Data
-----  --------------  -----------
zbar   REG_SZ          water
zfoo   REG_EXPAND_SZ   %zbar%

Open new cmd.exe, powershell.exe or whatever. These variables are missing. Make LogOff, then LogOn. In cmd.exe window type echo %zbar%water is displayed. Type echo %zfoo% and %zbar% is displayed, but I expect to see expanded value – water.

And now. Open Windows Environment Variables dialog. Alter or create any variable (for example zzz=zzz). Reopen cmd.exe and type echo %zfoo% – now you see water!

Actually, I am creating these variables with PowerShell script. But all this script does is described registry manipulations.

Questions:

  1. How to force zfoo variable to have a correct value without that magic with opening Windows Environment Variables dialog and altering some variables? Maybe I should call some API, something like [Microsoft.Win32.Registry]::Refresh()?
  2. It is possible to make these variables visible to users without need for LogOff/LogOn operations? If I edit user-level environment variables (also in registry) they are immediately available, but with global – they are not.

Thanks.

Best Answer

You need to broadcast the WM_SETTINGCHANGE Message.

Remember: You're not actually setting any environment variables of any form when you modify the registry. Environment variables are part of each individual process' memory space, with each process having its own set. They don't live in the registry. You are changing a template. You need to persuade the programs that set actual environment variables to re-read the template and set their environments accordingly. You do that by broadcasting a Windows message that tells any interested parties that the template in the registry has changed. Microsoft Windows Explorer is one such interested party, and modifies its own environment variables whenever it hears that the template has changed. These modifications are then inherited in the normal way by any new process that Explorer spawns.