#include-once ; corz registry functions v0.2.3.1 ; (c) corz.org 2006->tomorrow! #cs Miscelleneous Registry Comands @Extended values.. 0 = directory (key) 1 = REG_SZ 2 = REG_EXPAND_SZ 3 = REG_BINARY 4 = REG_DWORD 7 = REG_MULTI_SZ Function List.. MakeLongRegPaths() GetContextCommands() KeyIsEmpty() ReturnAllSubkeys() ReturnAllValueNames() ReturnAllPairs() SetExplorerContextMenu() #ce ; switch short (i.e "HKCU") registry paths, for "long" (i.e. "HKEY_CURRENT_USER") paths ; (doesn't AutoIt do this automatically yet?).. func MakeLongRegPaths($reg_key) $reg_key = StringReplace($reg_key, "HKCR", "HKEY_CLASSES_ROOT") $reg_key = StringReplace($reg_key, "HKCU", "HKEY_CURRENT_USER") $reg_key = StringReplace($reg_key, "HKU", "HKEY_USERS") $reg_key = StringReplace($reg_key, "HKLM", "HKEY_LOCAL_MACHINE") $reg_key = StringReplace($reg_key, "HKCC", "HKEY_CURRENT_CONFIG") return $reg_key endfunc ; ; GetContextCommands() ; ; return names of the context (right-click) commands ; of a particular file type as an "AutoIt array", that is, ; an array where the first value is the number of real ; values in the array (integer). ; ; $array = GetContextCommands("txtfile") ; func GetContextCommands($file_type) $file_type = "HKEY_CLASSES_ROOT\" & $file_type & "\Shell" local $dirs = "" local $y = 1 while $y local $var = RegEnumKey($file_type, $y) if @error <> 0 then exitloop if @extended = 0 then ; directory $dirs &= $var & "|" endif $y += 1 wend if $dirs <> "" then $dirs = StringTrimRight($dirs, 1) return StringSplit($dirs, "|") endif endfunc ; returns true is a given registry key is empty.. ; ; requires ReturnAllSubkeys() & ReturnAllValueNames() ; func KeyIsEmpty($key) local $reg_test_array_k = ReturnAllSubkeys($key) local $reg_test_array_v = ReturnAllValueNames($key) if $reg_test_array_k[1] = "" and $reg_test_array_v[1] = "" then return 1 endif endfunc ; ReturnAllSubkeys() ; returns all the subkeys of a registry key as an "AutoIt array" of key names.. ; eg. $array = ReturnAllSubkeys("HKCU\SOFTWARE\corz") ; ; requires MakeLongRegPaths($reg_key) ; func ReturnAllSubkeys($key) $key = MakeLongRegPaths($key) local $keys = "" local $x = 1 while $x local $var = RegEnumKey($key, $x) if @error <> 0 then exitloop if $var <> "" then $keys &= $var & "|" $x += 1 wend $keys = StringTrimRight($keys, 1) return StringSplit($keys, "|") endfunc ; ReturnAllValueNames() ; returns all the names of a registry key as an "AutoIt array" of names.. ; eg. $array = ReturnAllValueNames("HKCU\SOFTWARE\corz") ; ; requires MakeLongRegPaths($reg_key) ; func ReturnAllValueNames($key) $key = MakeLongRegPaths($key) local $names = "" local $x = 1 while $x local $var = RegEnumVal($key, $x) if @error <> 0 then exitloop if $var <> "" then $names &= $var & "|" $x += 1 wend ;if $names <> "" then $names = StringTrimRight($names, 1) return StringSplit($names, "|") ;endif endfunc ; ; ReturnAllPairs() ; ; returns all the name/value pairs from a registry key as a ; 2-dimensional "AutoIt array" of name/value pairs, starting at ; array[1][0]. array[0][0] contains the total number of pairs ; returned. Empty registry values can be skipped by passing the ; optional second parameter as true. ; ; ReturnAllPairs("HKCU\SOFTWARE\corz") ; #cs ReturnAllPairs example: ; ; display programs that run at startup for all users.. #include "corz_registry.au3" $str = "" $foo = ReturnAllPairs("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run") for $i = 1 to $foo[0][0] $str &= "key: " & $foo[$i][0] & " value: " & $foo[$i][1] & " " & @LF next MsgBox (0, "These programs run at startup..", $str) exit ; or the whole lot.. dim $startup_places[4] = _ [ "HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", _ "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run", _ "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce", _ "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnceEx" ] for $place in $startup_places $foo = ReturnAllPairs($place) for $i = 1 to $foo[0][0] $str &= $foo[$i][0] & " : " & $foo[$i][1] & " " & @LF next next MsgBox (0, "These programs run at startup..", $str) #ce func ReturnAllPairs($key, $skip_empties=false) local $x = 1 local $y = 1 local $pairs[1][2] while $x local $var = RegEnumVal($key, $x) if @error <> 0 then exitloop local $this_value = RegRead($key, $var) if (not $skip_empties) or ($skip_empties and $this_value <> "") then redim $pairs[$y+1][2] $pairs[$y][0] = $var $pairs[$y][1] = $this_value $y += 1 endif $x += 1 wend $pairs[0][0] = $y - 1 return $pairs endfunc ; ; SetExplorerContextMenu ; ; This sets an Explorer context item for an application. It can be either the default ; command for a particular filetype, or else simply another command on the context menu. ; ; This function relies on my $my_name convention, where $my_name is a global variable ; containing a string which is the name of the application, used to create subkeys, etc. ; ; Uses KeyIsEmpty() - Also in this collection. ; ; Parameters.. ; ; 1. $ext File Type extension to work with (minus the dot) ; 2. $switch $ON or $OFF, $GUI_CHECKED & $GUI_UNCHECKED, 1 or 4, whatever ; This switch enables or disables the explorer menu item, depending. ; 3. $default True if you wish to set the Explorer default command $ON/$OFF ; 4. $menu_item The string of text that will appear in the Explorer context menu ; Defaults to $my_name if left blank ; You can force the key name by putting it after a pipe character.. ; e.g.. "Edit KeyBind Script|Edit" ; 5. $fallback If no file type has been set for this file extension, you can ; specify one here. Will only be used if the file extension ; doesn't already have a type. It will not steal an extension. ; 6. $switches Any switches you would like to place in the command-line ; (they are placed between & , with a space added at either side) ; ; 7. $app_override Sets a different app as the default app. specify the full path to the app. ; Or provide the short name if the app is in the path, e.g. "notepad.exe" ; ; 8. $icon Specify the full string: "C:\path\to\resource.exe,0" ; ; ; You can use Default as any value except the first. ; ; If there are any issues, the function will set @Error to some non-zero value and return ; a useful message as the return value, which you can use directly. Successful operartions ; also return a message letting you know exactly what happened. ; ; ; Here is an example of setting TWO context commands.. ; ; SetExplorerContextMenu("kc", $associate_kc_files, true, "Run The Script", _ ; "KeyBind Commands File", "", @ScriptFullPath, @ScriptFullPath & ",4") ; SetExplorerContextMenu("kc", $associate_kc_files, false, "Edit KeyBind Script|Edit", "", "", $user_editor) ; ; ; Note the $associate_kc_files variable. If this is set to $ON and we run the two commands ; above we setup the context menu. Set that variable to $OFF and the entire registry ; structure will be cleanly removed. ; func SetExplorerContextMenu($ext, $switch=default, $default=default, $menu_item=default, _ $fallback=default, $switches=default, $app_override=default, $icon=default) if $switch = default then $switch = $OFF if $default = default then $default = $OFF if $menu_item = default or $menu_item = "" then $menu_item = "Open with " & $my_name & "|" & $my_name if $fallback = default then $fallback = "my-unique-key" if $switches = default then $switches = "" if $app_override = default then $app_override = "" if $icon = default then $icon = "" if not $ext then return SetError(1, 0, "no extension given") local $key if $default = $ON then $key = "open" ; set the default app for this file type else local $menu_array = StringSplit($menu_item, "|") debug_PrintArray($menu_array, "$menu_array:", @ScriptLineNumber, 0);debug $menu_item = $menu_array[1] $key = $menu_array[2] endif local $reg1, $reg2, $reg3, $reg4 local $filextkey = "HKEY_CLASSES_ROOT\." & $ext local $file_type = RegRead($filextkey, "") if not $file_type then $file_type = $fallback local $regbase = "HKEY_CLASSES_ROOT\" & $file_type local $shell = $regbase & "\shell" local $shellkey = $shell & "\" & $key local $BAX_key = $regbase & "\" & $my_name & "_Backup" local $my_app if $app_override then $my_app = $app_override else if @compiled then $my_app = @ScriptFullPath else $my_app = ".\" & $my_name & ".exe" endif endif ; user has this enabled. ; if $switch = $ON then debug("Adding Context Menu (" & $menu_item & ") for.. =>" & $ext & "<=", @ScriptLineNumber);debug local $extexist = RegRead($filextkey, "") if not $extexist then RegWrite($filextkey, "", "REG_SZ", $file_type) endif ; check if it's still enabled.. local $regexist = RegRead($shellkey & "\command", "") if StringInStr($regexist, $my_app) then return SetError(2, 0, "still enabled!") ; backup current key.. local $bax1, $bax2, $bax3, $bax4, $old_val, $old_key ; default shell command: "open" ; we don't simply set this to the \my_name command, because they could be two different commands. ; this is more flexible ; replacing default shell command.. if $default = $ON then $old_key = RegRead($shell, "") ; "open" or "02.other_command", etc. $bax1 = RegWrite($BAX_key, "", "REG_SZ", $old_key) $old_val = RegRead($shell & "\" & $old_key, "") ; "DO THIS.." $bax2 = RegWrite($BAX_key, "menu", "REG_SZ", $old_val) $old_val = RegRead($shell & "\" & $old_key & "\command", "") ; C:\Program Files\other-apps\some-app.exe "%1" $bax3 = RegWrite($BAX_key, "cmd", "REG_SZ", $old_val) ; "cmd" because "command" is reserved! $old_val = RegRead($regbase & "\defaulticon", "") $bax4 = RegWrite($BAX_key, "icon", "REG_SZ", $old_val) if not $old_key then RegWrite($BAX_key, "created", "REG_SZ", "yes") if not $bax1 or not $bax2 or not $bax3 or not $bax4 then return SetError(3, 0, "no backup") endif ; write new key.. $reg1 = RegWrite($shellkey, "", "REG_SZ", $menu_item) $reg2 = RegWrite($shellkey & "\command", "", "REG_SZ", '"' & $my_app & '" ' & $switches & ' "%1"') if $default = $ON then RegWrite($shell, "", "REG_SZ", "open") if $icon then RegWrite($regbase & "\defaulticon", "", "REG_SZ", $icon) if $reg1 and $reg2 then return SetError(0, 0, "Written OK!") else ; Switch OFF.. debug("Removing Context Menu for.. =>" & $ext & "<=", @ScriptLineNumber);debug $regexist = RegRead($shellkey & "\command", "") if not StringInstr($regexist, $my_app) then return SetError(4, 0, "already off!") ; okay, reg is in place, let's restore backup, if available, or delete keys.. local $old_key1, $old_key2, $old_key3, $old_key4, $old_key5 ; default command.. if $default = $ON then $old_key1 = RegRead($BAX_key, "") $old_key2 = RegRead($BAX_key, "menu") $old_key3 = RegRead($BAX_key, "cmd") $old_key4 = RegRead($BAX_key, "icon") $old_key5 = RegRead($BAX_key, "created") ; restore backup registry values.. if ($old_key1 and ($old_key2 or $old_key3 or $old_key4)) or $old_key5 then if $old_key5 <> "yes" then if $old_key1 then $reg1 = RegWrite($shell, "", "REG_SZ", $old_key1) if $old_key2 then $reg2 = RegWrite($shell & "\" & $old_key1, "", "REG_SZ", $old_key2) if $old_key3 then $reg3 = RegWrite($shell & "\" & $old_key1 & "\command", "", "REG_SZ", $old_key3) if $old_key4 then $reg4 = RegWrite("HKEY_CLASSES_ROOT\" & $old_key1 & "\defaulticon", "", "REG_SZ", $old_key4) endif endif if $reg1 and $reg2 and $reg3 and $reg4 then RegDelete($BAX_key) if $old_key5 = "yes" then RegDelete($regbase) RegDelete($filextkey) endif return SetError(0, 0, "SUCCESS!") endif else ; regular menu item, simply delete it.. local $restored = RegDelete($shellkey) if $restored then return SetError(0, 0, "Deleted!") endif endif return SetError(-1, 0, "nothing happened!") endfunc #cs Changes: 0.2 Added.. SetExplorerContextMenu() which I cooked up for LoopDropZ & MangleeZee. All yours! 0.1 A small selection of useful registry functions.. MakeLongRegPaths() GetContextCommands() KeyIsEmpty() ReturnAllSubkeys() ReturnAllValueNames() ReturnAllPairs() #ce