Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Change %ENV globally on Win32

by runrig (Abbot)
on Jul 01, 2005 at 21:17 UTC ( #471822=snippet: print w/replies, xml ) Need Help??
Description:

Update: modules Win32::Env and Win32::Env::Path(note: WEP does not broadcast the change) make this code obsolete.

Everyone (I hope) knows that changing environment variables only affects current and (subsequently spawned) child processes and doesn't affect parent or other unrelated processes. But on Windows, when you go through Control Panel to change environment variables, that's exactly what does happen (it changes environment variables in other processes). I had to do a bit of searching to find out how to do this, so just in case you ever need to do this, here it is. Might it be a good idea to wrap this up in a module...maybe Win32::EnvVar??

This program broadcasts to other Win32 processes a message to reload their environment. Other processes do not have to listen to the message. "CMD.EXE" and "PERL.EXE", e.g., do not reload their environment.

Note: There is also Win32::AdminMisc::SetEnvVar(), but it crashed perl when I ran it on Windows XP with ActiveState perl 5.8.4 build 810. Although other functions in the package worked fine.

Updated: Path is a REG_EXPAND_SZ...see GetValue() method in Win32::TieRegistry to see how get the type of other registry values/environment variables if you want a more dynamic solution.

Note: I very nearly used ActiveState's ActiveTcl for this, because it comes with a "broadcast" function in the "registry" package.


use strict;
use warnings;
my $Registry;
use Win32::TieRegistry (
  Delimiter => "/",
  TiedRef => \$Registry,
  "REG_EXPAND_SZ"
);
use Win32::API;

my $dir = "c:\\another_directory";

# Registry key for $ENV{PATH}
my $path_key = "LMachine/SYSTEM/CurrentControlSet/Control/Session Mana
+ger/Environment/Path";
die "Can't find Path registry key\n"
  unless exists $Registry->{$path_key};

my $path = $Registry->{$path_key};

$path .= ";$dir";
$Registry->{$path_key} = [ $path, REG_EXPAND_SZ ];

use constant HWND_BROADCAST   => 0xFFFF;
use constant WM_SETTINGCHANGE => 0x001A;
my $SendMessage = Win32::API->new("user32", "SendMessage", 
  [qw(N N P P)], "N");
my $result = $SendMessage
  ->Call(HWND_BROADCAST, WM_SETTINGCHANGE, 0, 'Environment');
Replies are listed 'Best First'.
Re: Change %ENV globally on Win32
by rvosa (Curate) on Jul 06, 2005 at 00:44 UTC
    Heh. That's good to know. Cheers.

    Mind you, I still have the innate urge not to mess around in the Windows registry. I can't help it, I started out on Win3.11 (not counting ms-dos and the commodore 64), and ever since then I've been told to recoil in fear at the mention, even, of regedit. Who knows? Your computer might stop functioning?! :)
      Yeah, the die is just there for the paranoia factor :-)
Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://471822]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others wandering the Monastery: (5)
As of 2019-07-22 22:34 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    If you were the first to set foot on the Moon, what would be your epigram?






    Results (22 votes). Check out past polls.

    Notices?