RefreshEnvironment() { ; load the system-wide environment variables first in case there are user-level ; variables with the same name (since they override the system definitions). Loop, HKLM, SYSTEM\CurrentControlSet\Control\Session Manager\Environment, 0, 0 { RegRead, vEnvValue If (A_LoopRegType == "REG_EXPAND_SZ") { If (!ExpandEnvironmentStrings(vEnvValue)) { Return False } } EnvSet, %A_LoopRegName%, %vEnvValue% } ; now load the user level environment variables Loop, HKCU, Environment, 0, 0 { RegRead, vEnvValue If (A_LoopRegType == "REG_EXPAND_SZ") { If (!ExpandEnvironmentStrings(vEnvValue)) { Return False } } EnvSet, %A_LoopRegName%, %vEnvValue% } ; return success. Return True } ExpandEnvironmentStrings(ByRef vInputString) { ; get the required size for the expanded string vSizeNeeded := DllCall("ExpandEnvironmentStrings", "Str", vInputString, "Int", 0, "Int", 0) If (vSizeNeeded == "" || vSizeNeeded <= 0) return False ; unable to get the size for the expanded string for some reason vByteSize := vSizeNeeded + 1 If (A_PtrSize == 8) { ; Only 64-Bit builds of AHK_L will return 8, all others will be 4 or blank vByteSize *= 2 ; need to expand to wide character sizes } VarSetCapacity(vTempValue, vByteSize, 0) ; attempt to expand the environment string If (!DllCall("ExpandEnvironmentStrings", "Str", vInputString, "Str", vTempValue, "Int", vSizeNeeded)) return False ; unable to expand the environment string vInputString := vTempValue ; return success Return True }
Function to Refresh Environment Variables
Started by
NoobSawce
, Feb 21 2011 12:31 AM
6 replies to this topic
Under normal circumstances, when a process is launched in Windows, it is passed a copy of the system's environment variables. This means that if another process updates one of the system's environment variables, your script won't get the changed value (although it may get a WM_SETTINGSCHANGE window message). This function allows you to "refresh" your copy of the environment variable with the system's copy defined in the registry. This script was tested on 32-Bit build of AHK_L, however I've written it so that it should work with any version of AHK, including basic.
#1
-
Posted 21 February 2011 - 12:31 AM
This function allows you to "refresh" your copy of the environment variable with the system's copy defined in the registry.
I found that this script loses the system setting for PATH and only sets the user PATH. Instead, the two must be merged. Here is my revised code to do that. I don't know if other environment variables require merging,
but it should not be hard to add them
RefreshEnvironment() { ; load the system-wide environment variables first in case there are user-level ; variables with the same name (since they override the system definitions). ; treat PATH and PATHEXT special - we must contactenate the user and system values. sysPATH := "" sysPATHEXT := "" Loop, HKLM, SYSTEM\CurrentControlSet\Control\Session Manager\Environment, 0, 0 { RegRead, vEnvValue If (A_LoopRegType == "REG_EXPAND_SZ") { If (!ExpandEnvironmentStrings(vEnvValue)) { Return False } } EnvSet, %A_LoopRegName%, %vEnvValue% if (A_LoopRegName = "PATH") { sysPATH := vEnvValue } else if (A_LoopRegName = "PATHEXT") { sysPATHEXT := vEnvValue } } ; now load the user level environment variables Loop, HKCU, Environment, 0, 0 { RegRead, vEnvValue If (A_LoopRegType == "REG_EXPAND_SZ") { If (!ExpandEnvironmentStrings(vEnvValue)) { Return False } } envVal := vEnvValue if (A_LoopRegName = "PATH") { envVal := envVal . ";" . sysPATH } else if (A_LoopRegName = "PATHEXT") { envVal := envVal . ";" . sysPATHEXT } EnvSet, %A_LoopRegName%, %envVal% } ; return success. Return True } ExpandEnvironmentStrings(ByRef vInputString) { ; get the required size for the expanded string vSizeNeeded := DllCall("ExpandEnvironmentStrings", "Str", vInputString, "Int", 0, "Int", 0) If (vSizeNeeded == "" || vSizeNeeded <= 0) return False ; unable to get the size for the expanded string for some reason vByteSize := vSizeNeeded + 1 If (A_PtrSize == 8) { ; Only 64-Bit builds of AHK_L will return 8, all others will be 4 or blank vByteSize *= 2 ; need to expand to wide character sizes } VarSetCapacity(vTempValue, vByteSize, 0) ; attempt to expand the environment string If (!DllCall("ExpandEnvironmentStrings", "Str", vInputString, "Str", vTempValue, "Int", vSizeNeeded)) return False ; unable to expand the environment string vInputString := vTempValue ; return success Return True }
(Updated to also concatenate PATHEXT)
#2
-
Posted 22 February 2011 - 03:56 PM
Forgot about that. PATHEXT is the other one that should merge system and user values. For the others (i.e. single value variables like TMP and TEMP), the user environment variables should override the system value. Nice catch.
EDIT: I probably didn't notice this because I don't use environment variables that much, so all of my systems are pretty much set to the default, which only defines a user level TMP and TEMP variable. Although, I've always found it wierd that USERPROFILE is a system level variable and not a user level one. :?
EDIT: I probably didn't notice this because I don't use environment variables that much, so all of my systems are pretty much set to the default, which only defines a user level TMP and TEMP variable. Although, I've always found it wierd that USERPROFILE is a system level variable and not a user level one. :?
#3
-
Posted 22 February 2011 - 05:40 PM
I updated the source above to also concatenate PATHEXT.Forgot about that. PATHEXT is the other one that should merge system and user values.
#4
-
Posted 22 February 2011 - 06:08 PM
I tried this after manually changing a value in:
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment]
But it did not update when I opened a new command prompt.
Windows XP SP3.
AHK_L Version v1.1.00.00 (2010)
MsgBox, start
x=RefreshEnvironment()
MsgBox, Done
Any thoughts?
[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment]
But it did not update when I opened a new command prompt.
Windows XP SP3.
AHK_L Version v1.1.00.00 (2010)
MsgBox, start
x=RefreshEnvironment()
MsgBox, Done
Any thoughts?
#5
-
Posted 18 June 2012 - 04:05 PM
x:=.....
And I get an error that AHK_L needs to close.....
And I get an error that AHK_L needs to close.....
#6
-
Posted 18 June 2012 - 04:24 PM
Shortest version:
RefreshEnvironment() { Path := "" PathExt := "" RegKeys := "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment,HKCU\Environment" Loop, Parse, RegKeys, CSV { Loop, Reg, %A_LoopField%, V { RegRead, Value If (A_LoopRegType == "REG_EXPAND_SZ" && !ExpandEnvironmentStrings(Value)) Continue If (A_LoopRegName = "PATH") Path .= Value . ";" Else If (A_LoopRegName = "PATHEXT") PathExt .= Value . ";" Else EnvSet, %A_LoopRegName%, %Value% } } EnvSet, PATH, %Path% EnvSet, PATHEXT, %PathExt% }Also if error occured while expanding string, function continues with next environment variable.
#7
-
Posted 22 October 2015 - 10:56 AM