Jump to content
Sign in to follow this  
hutchinsfairy

EnvUpdate() Hangs

Recommended Posts

hutchinsfairy

If I manually edit my environmental variables via the system properties --> advanced tab and then subsequently call "EnvUpdate()" from a script then Autoit hangs (indefinitely as far as I can tell).

Restarting my machine resolves the issue until I manually open the windows environmental variable window again.

Autoit v3.3.8.1

Share this post


Link to post
Share on other sites
FireFox

Hi,

Have you tried with the #RequireAdmin function ? With the latest beta ?

Try this (I don't know at all if it works) :

#include <WindowsConstants.au3>
#include <WinAPIEx.au3>

Local Const $HWND_BROADCAST = 0xFFFF
Local Const $SMTO_ABORTIFHUNG = 0x0002

_WinAPI_SendMessageTimeout($HWND_BROADCAST, $WM_SETTINGCHANGE, 0, "Environment", 0, $SMTO_ABORTIFHUNG)

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
hutchinsfairy

Sorry for not responding sooner, I was expecting to get emailed when someone replied!

Thank you for the suggestions!

The script already had #RequireAdmin set and I'm on Win XP so no UAC.

I haven't tried the latest Beta, hopefully I'll get a chance to tomorrow.

Is the snippet you've suggested supposed to be called by another autoit script to knock EnvUpdate() on the head?

(Just downloading the WinAPIEx UDF to test it...)

Share this post


Link to post
Share on other sites
FireFox

Is the snippet you've suggested supposed to be called by another autoit script to knock EnvUpdate() on the head?

No, replace the EnvUpdate function by my snippet in your script.

Br, FireFox.


 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
hutchinsfairy

Thanks again!

Unfortunately:

1) Running your code with either 3.3.8.1 or 3.3.9.4 doesn't cause any environmental variable updates to persist (latest WinAPIEx.au3)

2) Running EnvUpdate() causes my script to hang with both versions of AutoIT.

Share this post


Link to post
Share on other sites
FireFox

Try even his code looks the same as mine.

Br, FireFox.

  • Like 1

 

OS : Win XP SP2 (32 bits) / Win 7 SP1 (64 bits) / Win 8 (64 bits) | Autoit version: latest stable / beta.
Hardware : Intel(R) Core(TM) i5-2400 CPU @ 3.10Ghz / 8 GiB RAM DDR3.

My UDFs : Skype UDF | TrayIconEx UDF | GUI Panel UDF | Excel XML UDF | Is_Pressed_UDF

My Projects : YouTube Multi-downloader | FTP Easy-UP | Lock'n | WinKill | AVICapture | Skype TM | Tap Maker | ShellNew | Scriptner | Const Replacer | FT_Pocket | Chrome theme maker

My Examples : Capture toolIP Camera | Crosshair | Draw Captured Region | Picture Screensaver | Jscreenfix | Drivetemp | Picture viewer

My Snippets : Basic TCP | Systray_GetIconIndex | Intercept End task | Winpcap various | Advanced HotKeySet | Transparent Edit control

 

Share this post


Link to post
Share on other sites
guinness

Strange that EnvUpdate doesn't work.


UDF List:

 
_AdapterConnections()_AlwaysRun()_AppMon()_AppMonEx()_ArrayFilter/_ArrayReduce_BinaryBin()_CheckMsgBox()_CmdLineRaw()_ContextMenu()_ConvertLHWebColor()/_ConvertSHWebColor()_DesktopDimensions()_DisplayPassword()_DotNet_Load()/_DotNet_Unload()_Fibonacci()_FileCompare()_FileCompareContents()_FileNameByHandle()_FilePrefix/SRE()_FindInFile()_GetBackgroundColor()/_SetBackgroundColor()_GetConrolID()_GetCtrlClass()_GetDirectoryFormat()_GetDriveMediaType()_GetFilename()/_GetFilenameExt()_GetHardwareID()_GetIP()_GetIP_Country()_GetOSLanguage()_GetSavedSource()_GetStringSize()_GetSystemPaths()_GetURLImage()_GIFImage()_GoogleWeather()_GUICtrlCreateGroup()_GUICtrlListBox_CreateArray()_GUICtrlListView_CreateArray()_GUICtrlListView_SaveCSV()_GUICtrlListView_SaveHTML()_GUICtrlListView_SaveTxt()_GUICtrlListView_SaveXML()_GUICtrlMenu_Recent()_GUICtrlMenu_SetItemImage()_GUICtrlTreeView_CreateArray()_GUIDisable()_GUIImageList_SetIconFromHandle()_GUIRegisterMsg()_GUISetIcon()_Icon_Clear()/_Icon_Set()_IdleTime()_InetGet()_InetGetGUI()_InetGetProgress()_IPDetails()_IsFileOlder()_IsGUID()_IsHex()_IsPalindrome()_IsRegKey()_IsStringRegExp()_IsSystemDrive()_IsUPX()_IsValidType()_IsWebColor()_Language()_Log()_MicrosoftInternetConnectivity()_MSDNDataType()_PathFull/GetRelative/Split()_PathSplitEx()_PrintFromArray()_ProgressSetMarquee()_ReDim()_RockPaperScissors()/_RockPaperScissorsLizardSpock()_ScrollingCredits_SelfDelete()_SelfRename()_SelfUpdate()_SendTo()_ShellAll()_ShellFile()_ShellFolder()_SingletonHWID()_SingletonPID()_Startup()_StringCompact()_StringIsValid()_StringRegExpMetaCharacters()_StringReplaceWholeWord()_StringStripChars()_Temperature()_TrialPeriod()_UKToUSDate()/_USToUKDate()_WinAPI_Create_CTL_CODE()_WinAPI_CreateGUID()_WMIDateStringToDate()/_DateToWMIDateString()Au3 script parsingAutoIt SearchAutoIt3 PortableAutoIt3WrapperToPragmaAutoItWinGetTitle()/AutoItWinSetTitle()CodingDirToHTML5FileInstallrFileReadLastChars()GeoIP databaseGUI - Only Close ButtonGUI ExamplesGUICtrlDeleteImage()GUICtrlGetBkColor()GUICtrlGetStyle()GUIEventsGUIGetBkColor()Int_Parse() & Int_TryParse()IsISBN()LockFile()Mapping CtrlIDsOOP in AutoItParseHeadersToSciTE()PasswordValidPasteBinPosts Per DayPreExpandProtect GlobalsQueue()Resource UpdateResourcesExSciTE JumpSettings INISHELLHOOKShunting-YardSignature CreatorStack()Stopwatch()StringAddLF()/StringStripLF()StringEOLToCRLF()VSCROLLWM_COPYDATAMore Examples...

Updated: 22/04/2018

Share this post


Link to post
Share on other sites
hutchinsfairy

This is what I just ran:

#include <Array.au3>

Global $HWND_BROADCAST = 0xffff
Global $WM_SETTINGCHANGE = 0x001A
Global $SMTO_ABORTIFHUNG = 0x0002
Global $MSG_TIMEOUT = 5000


EnvSet("TEST", "HELLO")

ShellExecuteWait(@ComSpec)

$iRet2 = DllCall("user32.dll", "lresult", "SendMessageTimeoutW", _
"hwnd", $HWND_BROADCAST, _
"dword", $WM_SETTINGCHANGE, _
"ptr", 0, _
"wstr", "Environment", _
"dword", $SMTO_ABORTIFHUNG, _
"dword", $MSG_TIMEOUT, _
"dword_ptr*", 0)

ConsoleWrite(@CRLF & @error & @CRLF & @extended & @CRLF)

_ArrayDisplay($iRet2)

The variable is set as expected (if I launch @comspec "ECHO %TEST%" I get "HELLO" as expected).

The $iRet2[0] = 1 (i.e. no error as far as I understand). @error = 0 and @extended = 0

All looks good apart from the fact that after the script exits I see no change to my Environment Variables, either through the windows settings or in a fresh command prompt.

Edited by hutchinsfairy

Share this post


Link to post
Share on other sites
KaFu

Here's a function from way back :)...

#include-once
; http://www.autoitscript.com/forum/topic/116484-solved-autoit3-encountered-a-problem-and-needs-to-close/#entry813190
; #INDEX# =======================================================================================================================
; Title .........: Environment Update
; AutoIt Version.: 3.2.12++
; Language.......: English
; Description ...: Refreshes the OS environment.
; Author ........: João Carlos (jscript)
; Support .......: trancexx, PsaltyDS, KaFu
; ===============================================================================================================================

; #CURRENT# =====================================================================================================================
;_EnvUpdate
; ===============================================================================================================================

; #INTERNAL_USE_ONLY# ===========================================================================================================
; ===============================================================================================================================

; #VARIABLES# ===================================================================================================================
Global $MAX_VALUE_NAME = 1024
Global $HWND_BROADCAST = 0xffff
Global $WM_SETTINGCHANGE = 0x001A
Global $SMTO_ABORTIFHUNG = 0x0002
Global $SMTO_NORMAL = 0x0000
Global $MSG_TIMEOUT = 5000

; #Example# =====================================================================================================================
#cs
    _EnvUpdate("VERSION", "7.07.0110.2600")
    MsgBox(4096, @error, EnvGet("VERSION"))
    _EnvUpdate("VERSION", "", True, True)
    MsgBox(4096, @error, EnvGet("VERSION"))
#ce

_EnvUpdate("TEST", "HELLO")
ShellExecuteWait(@ComSpec) ; Try "ECHO %TEST%" => works during runtime of script...
ShellExecute(@ComSpec) ; Try "ECHO %TEST%" => should also work after script has finished :)...

; ===============================================================================================================================

; #FUNCTION# ====================================================================================================================
; Name...........: _EnvUpdate
; Description ...: Refreshes the OS environment.
; Syntax.........: _EnvUpdate( ["envvariable" [, "value" [, CurrentUser [, Machine ]]]] )
; Parameters ....: envvariable  - [optional] Name of the environment variable to set. If no variable, refreshes all variables.
;                  value        - [optional] Value to set the environment variable to. If a value is not used the environment
;                                   variable will be deleted.
;                  CurrentUser  - [optional] Sets the variable in current user environment.
;                  Machine      - [optional] Sets the variable in the machine environment.
; Return values .: Success      - None
;                  Failure      - Sets @error to 1.
; Author ........: João Carlos (jscript)
; Support .......: trancexx, PsaltyDS, KaFu
; Modified.......:
; Remarks .......:
; Related .......:
; Link ..........;
; Example .......; _EnvUpdate("TEMP", @SystemDir & "TEMP", True, True)
; ===============================================================================================================================
Func _EnvUpdate($sEnvVar = "", $vValue = "", $fCurrentUser = True, $fMachine = False)
    Local $sREG_TYPE = "REG_SZ", $iRet1, $iRet2

    If $sEnvVar <> "" Then
        If StringInStr($sEnvVar, "\") Then $sREG_TYPE = "REG_EXPAND_SZ"
        If $vValue <> "" Then
            If $fCurrentUser Then RegWrite("HKCU\Environment", $sEnvVar, $sREG_TYPE, $vValue)
            If $fMachine Then RegWrite("HKLM\System\CurrentControlSet\Control\Session Manager\Environment", $sEnvVar, $sREG_TYPE, $vValue)
        Else
            If $fCurrentUser Then RegDelete("HKCU\Environment", $sEnvVar)
            If $fMachine Then RegDelete("HKLM\System\CurrentControlSet\Control\Session Manager\Environment", $sEnvVar)
        EndIf
        ; http://msdn.microsoft.com/en-us/library/ms686206%28VS.85%29.aspx
        $iRet1 = DllCall("Kernel32.dll", "BOOL", "SetEnvironmentVariable", "str", $sEnvVar, "str", $vValue)
        If $iRet1[0] = 0 Then Return SetError(1)
    EndIf
    ; http://msdn.microsoft.com/en-us/library/ms644952%28VS.85%29.aspx
    $iRet2 = DllCall("user32.dll", "lresult", "SendMessageTimeoutW", _
            "hwnd", $HWND_BROADCAST, _
            "dword", $WM_SETTINGCHANGE, _
            "ptr", 0, _
            "wstr", "Environment", _
            "dword", $SMTO_ABORTIFHUNG, _
            "dword", $MSG_TIMEOUT, _
            "dword_ptr*", 0)

    If $iRet2[0] = 0 Then Return SetError(1)
EndFunc   ;==>_EnvUpdate

Share this post


Link to post
Share on other sites
hutchinsfairy

Here's a function from way back :)...

Thank you KaFu. That appears to be the same code that FireFox linked to. I have tested the DLLCALL as in my code above and it doesn't seem to work as expected. When I have a quiet moment at work I'll restart my machine and see what the exact steps are to recreate. Doesn't look likely today though...

Share this post


Link to post
Share on other sites
KaFu

Well, the code works fine for me on this XP machine. What I've noticed is that a process will get the current ENV settings on startup and will not be aware of any intermediate updates.

ShellExecute(@ComSpec) ; Try "ECHO %TEST%" => should also work after script has finished :)...

_EnvUpdate("TEST", "HELLO")

ShellExecute(@ComSpec) ; Try "ECHO %TEST%" => should also work after script has finished :)...

The first cmd.exe will not see the variable, the second will.

Share this post


Link to post
Share on other sites
hutchinsfairy

That's why I need to call EnvUpdate() so that the changes persists outside of the process tree.

Share this post


Link to post
Share on other sites
KaFu

Using the above example the change persists even if the script has ended.

It only seems to me that the default (?) behavior of a process is to load the ENV set only once at startup and that the WM_SETTINGCHANGE broadcast does not trigger a process to reload the env vars... and this seems like an none-AutoIt specific topic to me.

Share this post


Link to post
Share on other sites
hutchinsfairy

Using the above example the change persists even if the script has ended.

This is not what happens for me.

It only seems to me that the default (?) behavior of a process is to load the ENV set only once at startup and that the WM_SETTINGCHANGE broadcast does not trigger a process to reload the env vars... and this seems like an none-AutoIt specific topic to me.

I am not trying to get a process to reload the environment. I am trying to get changes made in my script to be available to other, new processes after my script ends. I'm sorry if that was not clear.

There are two presumably related issues here:

  • WM_SETTINGCHANGE does not make ENV VAR changes persist.
  • EnvUpdate() hangs when it tries to do the same.
I have just restarted my machine and EnvUpdate() hangs on a fresh boot. I have also noticed that if I update an existing ENV VAR and call WM_SETTINGCHANGE the ENV VAR appears to be unavailable to new processes. If I then bring up the windows ENV VAR dialog box and immediately click OK it seems to work again (with the original value, not what my script tried to set).

I'm wondering if it could be a group policy or something affecting my registry rights but have limited time to check. If the WM_SETTINGCHANGE call is supposed to work the same as EnvUpdate I might just use that, as at least it doesn't cause the whole script to hang. At best it will work as hoped on most computers and at worst the ENV VAR will remain unset.

Share this post


Link to post
Share on other sites
KaFu

Here's the MSDN documentation:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms682653(v=vs.85).aspx

What OS are you running on?

Maybe give this a try:

_EnvUpdate("TEST", "HELLO", False, True)

This will write variable to HKLM (add #RequireAdmin to top of the script on Vista+).

Also check these registry locations after the test to see whether the keys have been written successfully:

HKCUEnvironment

HKLMSystemCurrentControlSetControlSession ManagerEnvironment

  • Like 1

Share this post


Link to post
Share on other sites
hutchinsfairy

Windows XP SP3.

After another restart the situation is thus:

I can get my script to update the registry and then run the _EnvUpdate() UDF, and the changes persist beyond the termination of my script. Yay!

However, the shipped function EnvUpdate() still never completes on my machine.

I guess my original problem still stands but I have a workable workaround.

Thank you FireFox and KaFu.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

×