Luigi Posted July 30, 2014 Share Posted July 30, 2014 (edited) I need improve the use of _WinAPI_RegNotifyChangeKeyValue and build this UDF to tracking many windows's registry keys. It allows you add a function to change's of windows registry. You can add many windows registry key's with function's associate. If the function is not exist, they block function 'function.status' and not execute it more. It is possible define a time's delay to prevent a function's re-execution. You can help-me, rating about: -UDF is write in AutoIt UDF standards; -suggest best practices to improve code; -alert bugs or errors. -more... if you want... BR, Luigi. Example expandcollapse popup#include <RegistryMonitor.au3> Opt("MustDeclareVars", 1) HotKeySet('^+{END}', '_quit') ; Ctrl + Shift + {END} Local $reg1 = reg_monitor_add($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', BitOR($KEY_NOTIFY, $KEY_WOW64_64KEY), Default, 'ExampleFunctionA') ConsoleWrite('reg1[ ' & $reg1 & ' ]' & @LF) Local $reg2 = reg_monitor_add($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', $KEY_NOTIFY, Default, 'ExampleFunctionB') ConsoleWrite('reg2[ ' & $reg2 & ' ]' & @LF) Func ExampleFunctionA() ConsoleWrite('ExampleFunction[ SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall ]' & @LF) EndFunc ;==>ExampleFunctionA Func ExampleFunctionB() ConsoleWrite('ExampleFunction[ SOFTWARE\Microsoft\Windows\CurrentVersion\Run ]' & @LF) EndFunc ;==>ExampleFunctionB AdlibRegister('teste_one', 1000) AdlibRegister('teste_two', 5000) AdlibRegister('_quit', 8000) While Sleep(100) WEnd Func teste_one() Local $hWrite = RegWrite('HKEY_LOCAL_MACHINE64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'TEST_KEY', 'REG_SZ', 'Hello this is a test') ConsoleWrite('$hWrite[ ' & $hWrite & ' ]' & @LF) Sleep(1000) Local $hRemove = RegDelete('HKEY_LOCAL_MACHINE64\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', 'TEST_KEY') ConsoleWrite('$hRemove[ ' & $hRemove & ' ]' & @LF) AdlibUnRegister('teste_one') EndFunc ;==>teste_one Func teste_two() Local $hWrite = RegWrite('HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run', 'TEST_KEY', 'REG_SZ', 'Hello this is a test') ConsoleWrite('$hWrite[ ' & $hWrite & ' ]' & @LF) Sleep(1000) Local $hRemove = RegDelete('HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run', 'TEST_KEY') ConsoleWrite('$hRemove[ ' & $hRemove & ' ]' & @LF) AdlibUnRegister('teste_two') EndFunc ;==>teste_two Func _quit() Beep(1400, 200) Exit EndFunc ;==>_quit RegistryMonitor.au3 expandcollapse popup#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_AU3Check_Parameters= -q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 #Tidy_Parameters=/sf #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include-once #include <APIRegConstants.au3> #include <WinAPIDiag.au3> #include <WinAPIReg.au3> Opt('MustDeclareVars', 1) ; #INDEX# ======================================================================================================================= ; Title .........: registry_monitor ; AutoIt Version : 3.3.12.0 ; Description ...: Monitoring key's windows registry and associates a function this event ; Author(s) .....: HelpFile http://www.autoitscript.com/autoit3/docs/libfunctions/_WinAPI_RegNotifyChangeKeyValue.htm ; Modified ......: Detefon ; =============================================================================================================================== ; #VARIABLES# =================================================================================================================== Global $oEvents_RegistryMonitor = ObjCreate('Scripting.Dictionary') $oEvents_RegistryMonitor.Comparemode = 1 ; =============================================================================================================================== ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __reg_monitor_eval_key ; Description ...: Check if $iKey is a valid windows key ; Syntax.........: __reg_monitor_eval_key($iKey) ; Parameters ....: $iKey - Integer. The value must be/represent a registry windows key ; Return values .: Boolean ; Author ........: Detefon ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __reg_monitor_eval_key($iKey) If ($iKey == $HKEY_CLASSES_ROOT) Or ($iKey == $HKEY_CURRENT_CONFIG) Or ($iKey == $HKEY_CURRENT_USER) Or ($iKey == $HKEY_LOCAL_MACHINE) Or ($iKey == $HKEY_USERS) Then Return 1 Return 0 EndFunc ;==>__reg_monitor_eval_key ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __reg_monitor_eval_subkey ; Description ...: Check if $sSubkey contains less of 32 terms ; Syntax.........: __reg_monitor_eval_subkey($sSubkey) ; Parameters ....: $sSubkey - String. The value is a path's registry windows ; Return values .: Boolean ; Author ........: Detefon ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __reg_monitor_eval_subkey($sSubkey) Local $aSubkey = StringSplit($sSubkey, '\') If $aSubkey[0] >= 32 Then Return 0 Return 1 EndFunc ;==>__reg_monitor_eval_subkey ; #INTERNAL_USE_ONLY# =========================================================================================================== ; Name...........: __reg_monitor_eval_stop ; Description ...: Used when script is terminated, to close the opened handles (_WinAPI_RegCloseKey, _WinAPI_CloseHandle) ; Syntax.........: __reg_monitor_eval_stop() ; Parameters ....: none ; Return values .: none ; Author ........: Detefon ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func __reg_monitor_eval_stop() AdlibUnRegister('registry_monitor') For $each In $oEvents_RegistryMonitor ConsoleWrite('close key[ ' & $each & ' ] value[ ' & $oEvents_RegistryMonitor.Item($each).Item('handle') & ' ]' & @LF) If Not _WinAPI_RegCloseKey($oEvents_RegistryMonitor.Item($each).Item('handle')) Then ConsoleWrite('@error._WinAPI_RegCloseKey..........[ ' & _WinAPI_GetErrorMessage(@extended) & ' ]' & @LF) If Not _WinAPI_CloseHandle($oEvents_RegistryMonitor.Item($each).Item('main')) Then ConsoleWrite('@error._WinAPI_CloseHandle..........[ ' & _WinAPI_GetErrorMessage(@extended) & ' ]' & @LF) Next EndFunc ;==>__reg_monitor_eval_stop ; #FUNCTION# ==================================================================================================================== ; Name...........: reg_monitor_add ; Description ...: Add a key's registro to monitoring and associate this to the function ; Syntax.........: reg_monitor_add($iKey = 0, $sSubkey = '', $iOpt = 0, $iDelay = 5000, $sFunction = '') ; Parameters ....: $iKey - Integer. The value must be/represent a registry windows key ; $sSubkey - String. The value is a path's registry windows ; $iOpt - Integer. Positive. The value define a time in mileseconds to prevent function's re-execution. ; Default value is 5.000 msec or 5 seconds ; $sFunction - String. The name of function is called when event is happend ; Return values .: Handle's _WinAPI_RegOpenKey ; Author ........: Detefon ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func reg_monitor_add($iKey = 0, $sSubkey = '', $iOpt = 0, $iDelay = 5000, $sFunction = '') If $oEvents_RegistryMonitor.Exists($iKey & $sSubkey) Then Return SetError(1, 0, 1) ; prevent add function for same key Local $oTemp = ObjCreate('Scripting.Dictionary') $oTemp.Comparemode = 1 If Not __reg_monitor_eval_key($iKey) Then Return SetError(1, 0, 2) ; check if $iKey is valid If Not __reg_monitor_eval_subkey($sSubkey) Or ($sSubkey == '') Then Return SetError(1, 0, 3) ; check if $sSubkey is valid $iOpt = Number($iOpt) If $iOpt < 0 Then $iOpt = Abs($iOpt) Local $hKey = _WinAPI_RegOpenKey($iKey, $sSubkey, $iOpt) If @error Then Return SetError(1, 0, _WinAPI_GetErrorMessage(@extended)) If Not _WinAPI_RegQueryReflectionKey($hKey) Then Return SetError(1, 0, _WinAPI_GetErrorMessage(@extended)) $oTemp.Add('main', _WinAPI_CreateEvent()) If Not $oTemp.Item('main') Then Return SetError(1, 0, _WinAPI_GetErrorMessage(@extended)) If Not _WinAPI_RegNotifyChangeKeyValue($hKey, $REG_NOTIFY_CHANGE_LAST_SET, 1, 1, $oTemp.Item('main')) Then If @error Then Return SetError(1, 0, _WinAPI_GetErrorMessage(@extended)) EndIf If Not $sFunction Then Return SetError(1, 0, 4) $oTemp.Add('handle', $hKey) $oTemp.Add('function', $sFunction) $oTemp.Add('function.status', 1) $oTemp.Add('lasthit', 0) $oTemp.Add('delay', $iDelay) $oEvents_RegistryMonitor.Add($iKey & $sSubkey, $oTemp) AdlibRegister('registry_monitor', 100) OnAutoItExitRegister('__reg_monitor_eval_stop') Return $hKey EndFunc ;==>reg_monitor_add ; #FUNCTION# ==================================================================================================================== ; Name...........: registry_monitor ; Description ...: Verify if happened a notify's windows registry ; Syntax.........: Called by reg_monitor_add ; Parameters ....: none ; Return values .: none ; Author ........: Detefon ; Modified.......: ; Remarks .......: ; Related .......: ; Link ..........: ; Example .......: No ; =============================================================================================================================== Func registry_monitor() For $each In $oEvents_RegistryMonitor If Not _WinAPI_WaitForSingleObject($oEvents_RegistryMonitor.Item($each).Item('main'), 0) Then If _ $oEvents_RegistryMonitor.Item($each).Item('function.status') And _ ; if 'function.status' is valid, continue or not execute invalid function (($oEvents_RegistryMonitor.Item($each).Item('lasthit') == 0) Or _ ; if 'lasthit' is 0, continue ('function' is never hited) (TimerDiff($oEvents_RegistryMonitor.Item($each).Item('lasthit')) > ($oEvents_RegistryMonitor.Item($each).Item('delay')))) _ ; prevent reuse function in time less than delay time Then $oEvents_RegistryMonitor.Item($each).Item('lasthit') = TimerInit() ; mark the last use time's function Call($oEvents_RegistryMonitor.Item($each).Item('function')) ; call the function If @error == 0xDEAD And @extended == 0xBEEF Then $oEvents_RegistryMonitor.Item($each).Item('function.status') = 0 ; if error, set 'function.status' equal 0 EndIf If Not _WinAPI_RegNotifyChangeKeyValue($oEvents_RegistryMonitor.Item($each).Item('handle'), $REG_NOTIFY_CHANGE_LAST_SET, 0, 1, $oEvents_RegistryMonitor.Item($each).Item('main')) Then ExitLoop EndIf Next EndFunc ;==>registry_monitor Edited March 27, 2016 by Luigi falcontechnics 1 Visit my repository Link to comment Share on other sites More sharing options...
falcontechnics Posted March 26, 2016 Share Posted March 26, 2016 First of all thank you for your efforts. I ask for your help with something. "Registry_monitor" function did not understand. Very simple example "reg_monitor_add" and "reg_monitor" function is able to show you the use of? Local $reg1 = reg_monitor_add($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', BitOR($KEY_NOTIFY, $KEY_WOW64_64KEY), Default) Local $reg2 = reg_monitor_add($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Run', $KEY_NOTIFY, Default) Local $reg3 = reg_monitor_add($HKEY_LOCAL_MACHINE, 'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall', BitOR($KEY_NOTIFY, $KEY_WOW64_64KEY), Default) Link to comment Share on other sites More sharing options...
Luigi Posted March 27, 2016 Author Share Posted March 27, 2016 @falcontechnics, thank you. But this UDF is only to detect if a registry's key is changed or not... It not (properly) change a registry's key. See this funcionts: https://www.autoitscript.com/autoit3/docs/functions/RegWrite.htm RegDelete, RegEnumKey, RegEnumVal, RegRead Br falcontechnics 1 Visit my repository Link to comment Share on other sites More sharing options...
falcontechnics Posted March 27, 2016 Share Posted March 27, 2016 You're right. But I also want to take action until the monitor registry changes. You do not see my job this UDF ? Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now