tags:

views:

51

answers:

2

I would like to make a .bat file that would add some string at the end of the value of the Windows PATH variable. Warning, I want this change to be definitive, not working only for the current session.

Does somebody know of a way to do this ? As much as possible it should not be dependent on the version of Windows

A: 

Sorry for the long answer, but a short answer on your question is impossible.

First of all you should understand how environment variables works. There are some places in Registry like HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and HKEY_CURRENT_USER\Environment where the environment variables will be hold. At the start time operation system read this registry keys. Then one windows process create another windows process. The parent process can give to the client process any set of environment variables. If the parent process don't do this, the child process inherit environment variables of the parent processes.

To be able update environment variables of a running process with respect of WM_WININICHANGE or WM_SETTINGCHANGE messages. An windows application can interpret this messages and reread current environment variables from the registry HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment and HKEY_CURRENT_USER\Environment. So you can in general change registry values under HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment or HKEY_CURRENT_USER\Environment and send

SendMessage (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment");

It wold be much better to use SendMessageTimeout instead of SendMessage, but the idea will stay the same. The problem is that other processes must not wait for the message and do something. The most console application has no message loop and don't do anything if you send such messages.

So it is important to understand that there are no simple way to update environment variables of all processes without restarting of the computer. So you should clear understand this and reduce your question a little.

If you update Environment in registry and send SendMessage (HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment") then new processed created by Explorer.exe will be have new environment variables, but no cmd.exe will do this.

If you want to update environment variables of the current cmd.exe where the batch run you can do following. You can create a new CMD file for example t.cmd in %TEMP% directory, write in the file SET PATH=%PATH%;C:\BlaBla and then use call %TEMP%\t.cmd and dell %TEMP%\t.cmd to update environment variables of the current cmd.exe.

To be exactly there are more places which are used to build environment variables of new created processes. This are subkeys of the key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths and %SystemRoot%\System32\autoexec.nt file. One will be used for processes created by ShellExecute and ShellExecuteEx (for example Explorer.exe) and another for console applications.

Oleg
Wow, thanks a lot for the detailed answer. I am sure it will be valuable for other peoples too. That said, I a m a bit disappointed when I think how easy it is to do such thing in Linux.
madewulf
A: 

If you only care about new process instances, and you really want it to be done via a batch file, then setx is what you're looking for.

If you want to directly change an environment variable for currently running processes, well, yeah, that's complicated and apparently not recommended:

Altering the environment variables of a child process during process creation 
is the only way one process can directly change the environment variables of 
another process. A process can never directly change the environment variables 
of another process that is not a child of that process.

Otherwise, like Oleg says, programmatically the best way is to change the registry and send WM_SETTING_CHANGE and hope the apps are nice enough to pick it up.

jrtipton