2

I do not have the ability to modify environment variables in windows 7. However I have been granted permission to modify the registry settings. So for example I can modify: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment Key: BPATH which is appended to the end of my System's pathEnv.

but when I make the changes the change does not take affect until the next reboot.

I would like to find a command line that is "Always Installed" that can signal a change in BPATH such that "PATH" is always updated for subsequent programs and windows.

rundll user32.dll, [ BroadcastSystemMessage PATH CHANTGED... or somehting...]

Conditions:

  1. I can only edit the path and bpath via the registry, not from the System, Advanced tab...
  2. I do not want to install any software that is not part of a standard out of the box windows 7 install.
  3. Typically this should just be done from the CMD prompt of the PowerShell prompt.
mklement0
  • 382,024
  • 64
  • 607
  • 775
Q Boiler
  • 1,187
  • 9
  • 20

3 Answers3

2

This sounds difficult, and cannot be done with the rundll32 - I know because I have tried. There are many questions here, where the documentation of rundll is linked from. This basically only calls functions of the form:

 void CALLBACK
  EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

http://support.microsoft.com/kb/164787

Which means - you can call special functions, which were designed to be called with this tool, AND simple functions, which take no arguments, or maybe just a HWND.

To refresh the environment, you need to broadcast (i.e. SendMessageTimeout to HWND_BROADCAST) the WM_SETTINGCHANGE message, 4th argument (wparam) should be 0, and the LPARAM should be L"Environment" (notice the L - it has to be a wide string, or the variables won't refresh!).

Here's some working PS code, which I don't remember who wrote (it's actually the MSDN example for WM_SETTINGCHANGE translated from C++):

    #requires -version 2

    if (-not ("win32.nativemethods" -as [type])) {
        # import sendmessagetimeout from win32
        add-type -Namespace Win32 -Name NativeMethods -MemberDefinition @"
    [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    public static extern IntPtr SendMessageTimeout(
        IntPtr hWnd, uint Msg, UIntPtr wParam, string lParam,
        uint fuFlags, uint uTimeout, out UIntPtr lpdwResult);
    "@
    }

    $HWND_BROADCAST = [intptr]0xffff;
    $WM_SETTINGCHANGE = 0x1a;
    $result = [uintptr]::zero

    # notify all windows of environment block change
    [win32.nativemethods]::SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE,
            [uintptr]::Zero, "Environment", 2, 5000, [ref]$result);

It's more than 1 command, but fits into a small script.

I haven't tried your trick with a variable within a variable (PATH), but it may be, that such a configuration requires two subsequent refreshes (the first one allows BPATH to be updated, and on the second one PATH uses the updated BPATH value.

mklement0
  • 382,024
  • 64
  • 607
  • 775
Tomasz Gandor
  • 8,235
  • 2
  • 60
  • 55
1

Powershell:

[Environment]::SetEnvironmentVariable("path",[Environment]::GetEnvironmentVariable("path"),"Machine")

There you go, Set the Path Machine Variable to it's self

(Be aware that if you changed 'path', and it didn't update for Explorer.exe, Powershell would probably reset the current environment again!)

Asaf Levy
  • 11
  • 2
1

In Powershell, the following command will set the System variable 'variableName' the value of variableValue. The last value can be Machine,User or Process

PS C:\>[Environment]::SetEnvironmentVariable("variableName","variableValue","Machine")

The shell sends an update environment broadcast to the system. Any open shells will not receive the new environment variable.

toxicate20
  • 5,270
  • 3
  • 26
  • 38
Stephen
  • 11
  • 1