0

In Windows, the registry entry HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path contains the contents of the PATH environment variable. In my case, the PATH environment variable is of type REG_EXPAND_SZ, with the contents:

%SOME_PATH%\bin;C:\Windows

In addition, I have a user environment variable named PATH, which is defined as:

%PATH%;C:\Users\Me\Bin

If I type ECHO %PATH% on the command line, the output is:

C:\Some\Path\bin;C:\Windows;C:\Users\Me\Bin

OK, now for the desired result given the above scenario. I want to permanently prepend the machine's PATH variable from within a batch script. After the change, I want all newly opened command windows to pick up my change without the need to log off or restart, and the aforementioned registry value should be changed to:

C:\My\Path;%SOME_PATH%\bin;C:\Windows

Searching the web on how to do this yields the following approaches:

1) SETX Path "C:\My\Path;%Path%" /m

   Result: C:\My\Path;C:\Some\Path\bin;C:\Windows;C:\Users\Me\Bin

   The first problem with this is that it expands the %SOME_PATH% environment
   variable to it's corresponding value.  The second is that %Path% expands
   to include the user's Path variable.

2) REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"^
       /v Path /t REG_EXPAND_SZ /d "C:\My\Path;%%B" /f

   Result: C:\My\Path;%SOME_PATH%\bin;C:\Windows

   The registry value ends up being correct, but I have to log off or
   restart to pick up the changes.

Is there a way to accomplish what I am trying to do from within a Batch file?

Jeff G
  • 4,470
  • 2
  • 41
  • 76
  • 1
    The easiest way to do this from batch is to modify the registry using `reg add` and then call `setx` to change a dummy environment variable. When the dummy change is broadcast, Explorer reloads the environment table, including the change to PATH. – Harry Johnston Oct 13 '16 at 01:24
  • I strongly recommend not prepending your folder path, but appending your folder path. Only bad written installers and malware applications prepend a folder path to PATH which could easily result in lots of applications and batch scripts not working anymore if `%SystemRoot%\System32` is not first folder path anymore in system PATH depending on which executables and scripts the prepended folder path contains. See answer on [Why are other folder paths also added to system PATH with SetX?](http://stackoverflow.com/a/25919222/3074564) for an example on how to append a folder path to system PATH. – Mofi Oct 13 '16 at 06:05
  • @Mofi Unfortunately, Cygwin is installed on the target computers. Two of the applications I need to add to the path are *Perl* and *PostgreSQL*, both of which are included in the Cygwin install. Since I know appending the paths won't work in this instance, I decided to prepend instead. I'm also not happy about it, but I can't figure out a reliable way to insert my paths just before the Cygwin entry. There is no way to know if the path entry will be "C:\Cygwin\bin" or "%CW_DIR%\bin", since it isn't actually installed software. – Jeff G Oct 13 '16 at 14:29

1 Answers1

2

As indicated by @Harry Johnston in his comment, the solution is to call SETX on a dummy variable after changing the registry value. In my case, the code changed to:

REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment"^
   /v Path /t REG_EXPAND_SZ /d "C:\My\Path;%%B" /f
SETX OS "%OS%" /M

I verified that the WM_SETTINGCHANGE message does NOT include the name of the environment variable that was changed, so a client (such as explorer) that processes that message must refresh all environment variables when it is received. Proof is that the message only contains two parameters, wParam and lParam, which are set as follows when changing environment variables:

wParam
When an application sends this message, this parameter must be NULL.

lParam
To effect a change in the environment variables for the system or the user, broadcast this message with lParam set to the string "Environment".

Jeff G
  • 4,470
  • 2
  • 41
  • 76
  • I tried this and it set my path to _litterally_ "C:\My\Path;%%B" the %%B didn't get expanded into anything. How is that supposed to work? – Sam Hasler Jul 03 '20 at 14:11
  • 1
    I must have had the code in a for loop, which wasn't posted as part of my question. You have to get the registry key prior to updating the variable, so you will need to call `REG QUERY` in a for loop to populate the value into a named variable. In this case, the named variable is `%%B`. – Jeff G Jul 04 '20 at 15:49