warrendodge has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to use Tie::Registry to make changes to the registry. I can
do that just fine. But what I want is that those changes be made
available to all the current environment of windows so that the next
application that is executed will see the changes.


Here is the script I am trying.

-----------------------------------------------------------------------------
use Win32::TieRegistry ( Delimiter=>"/");

$Registry->{CUser}->{Environment}->{XXX} = "YYY";
-----------------------------------------------------------------------------

In the current "cmd" window the XXX variable is not in the environment
after executing the script. This I expect.

Using regedit you can see the XXX variable has indeed been set in the
registry.

Start->run->cmd  This new command window does not see the XXX variable
                 either. But I expected it would.

We had been using The Win32::AdminMisc package in the past and it
operated as I would expect. However, I haven't been able to bring it
forward to later versions of perl. In looking at that C code I found
this routine which was executed after each variable setting.

DWORD dwMessageResult = 0;
SendMessageTimeout(	HWND_BROADCAST, 
                        WM_WININICHANGE, 
                        0, 
                        (LPARAM) "Environment",
                        SMTO_ABORTIFHUNG,
                        dwTimeout,
                        &dwMessageResult );

I believe this will signal all the processes that they should update
their environment variables from the registry.

We have also found that using the command "setx" we can cause the
changes to the registry to be sent to all the processes. Currently we
are using this method:   setx x x and set a dummy variable.

What I am looking for is a "more refined" way to do this. It would be
really nice if Tie::Registry could provide a function/param to cause
changes to be seen by the environment.

Any help in this area will be greatly appreciated.

  • Comment on how do you propagate Tie::Registry modifications to the system environment

Replies are listed 'Best First'.
Re: how do you propagate Tie::Registry modifications to the system environment
by Khen1950fx (Canon) on Jul 22, 2010 at 06:46 UTC
    To broadcast the changes that you've made, you can use Win32::Env like this:
    #!/usr/bin/perl use strict; use warnings; use Win32::Env; InsertPathEnv(ENV_SYSTEM, PATH => $bindir); InsertPathEnv(ENV_SYSTEM, PERL5LIB => $libdir); BroadcastEnv();
    FYI, Win32::TieRegistry is the module that you want to use. Tie::Registry has been deprecated.

      Thanks for the info on Win32::Env and the Broadcast function. It seems to do the trick most of the time.

      We are trying to use the Win32::Env Broadcast function. It seems to work fine in most cases.

      We have found one machine where the function hangs. It has been trying for 8 minutes now and will not complete.

      The test case we are using is with perl version 5.8.8 822 from activestate. I installed Win32::Env 0.03 a few weeks ago.

      This is the script we are trying. It failed in a much larger script and we found this fails also.

      use Win32:Env;
      Broadcast();

      Do you know why this might happen? It there some sort of debug that can be enabled to see what it is trying to do?

        Do you even glance at the source code? (http://cpansearch.perl.org/src/ROWAA/Win32-Env-0.03/lib/Win32/Env.pm) BroadcastEnv() is extremely simple. It boils down to the equivalent of:

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

        If you want to debug that, you should probably use something like Spy++ (part of Visual Studio).

        It taking a long time probably means that you have a service or similar process that is hung.

        - tye