Updating Windows Environment Variables

A well-known fact is that, in order to permanently set/modify an environment variable, one should update the Registry under:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment (System Variable)

or

HKEY_CURRENT_USER\Environment (User Variable)

However, this update does not go into effect until logging off and back on.

The solution is to broadcast a Windows Message to all running applications. The following C++ code provides the details:

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) "Environment", SMTO_ABORTIFHUNG, 5000, &dwReturnValue);

In Perl, you can simply use the AdminMisc module to set environment variables. If you prefer to stick to standard modules (perl 5.8.9 and later), you can use the following code fragment:

use Win32::API;

	use constant HWND_BROADCAST => -1;
	use constant WM_SETTINGCHANGE => 0x1a;

	my $SendMessage = new Win32::API("user32", "SendMessage",
'NNNP', 'N')
    	or die "Couldn't create SendMessage: $!\n";
	my $RetVal =
$SendMessage->Call(HWND_BROADCAST,WM_SETTINGCHANGE,0,'Environment');

Another alternative is to build the aforementioned C++ code into a small exe file, and use this utility anywhere you like.

In any case, note that the environment variable change will not be visible to the calling process. You’ll need to set it internally (for example, using $ENV in Perl) if you need it to be available inside the script.

References: Microsoft KB Article 104011, PerlMonks thread

Advertisements