corz.org text viewer..
[currently viewing: /public/machine/source/windows/AutoIt Includes/corz_registry.au3 - raw]
#include-once

; corz registry functions v0.2
; (c) cor + 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()
        GetConceptCommands()
        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


;
; GetConceptCommands()
;
; return names of the concept (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 = GetConceptCommands("txtfile")
;
func GetConceptCommands($file_type)

    $file_type = "HKEY_CLASSES_ROOT\" & $file_type & "\Shell"
    $dirs = ""
    $y = 1
    while $y
        $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)
    $reg_test_array_k = ReturnAllSubkeys($key)
    $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)
    $keys = ""
    $x = 1
    while $x
        $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)
    $names = ""
    $x = 1
    while $x
        $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)

    $x = 1
    $y = 1
    local $pairs[1][2]

    while $x
        $var = RegEnumVal($key$x)
        if @error <> 0 then exitloop
        $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 concept 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
;        4. $menu_item    The string of text that will appear in the Explorer context menu
;                        Defaults to $my_name if left blank
;        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 <app> & <path>, with a space added at either side)
;
;
func SetExplorerContextMenu($ext$switch=4, $default=false, $menu_item=""$fallback="my-unique-key"$switches="")

    if not $ext then return false
    local $key = $my_name
    if $default then $key = "open"    ; become the default app for this file type
    if not $menu_item then $menu_item = $my_name

    local $reg1$reg2$reg3
    local $file_type = RegRead("HKEY_CLASSES_ROOT\." & $ext"")                                "soundrec"
    if not $file_type then $file_type = $fallback
    local $shell = "HKEY_CLASSES_ROOT\" & $file_type & "\shell"                                    ;    HKEY_CLASSES_ROOT\soundrec\shell
    local $shellkey = $shell & "\" & $key                                                        ;    HKEY_CLASSES_ROOT\soundrec\shell\(MyAPP || open)
    local $BAX_key = "HKEY_CLASSES_ROOT\" & $file_type & "\" & $my_name & "_Backup\" & $key        ;    HKEY_CLASSES_ROOT\soundrec\MyAPP_Backup\(MyAPP || open)

    if @compiled then
        $me_app = @ScriptFullPath
    else
        $me_app = ".\" & $my_name & ".exe"
    endif

    ; user has this enabled.
    if $switch = 1 then

        ; check if it's still enabled..
        $regexist = RegRead($shellkey & "\command""")
        if StringInStr($regexist, RemoveExtension(BaseName(@ScriptName))) then return true

        ; backup current key..
        local $bax1$bax2$bax3$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 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!
            if not $bax1 and $bax2 and $bax3 then return false
        endif

        ; write new key..
        $reg1 = RegWrite($shellkey"""REG_SZ"$menu_item)
        $reg2 = RegWrite($shellkey & "\command""""REG_SZ", '"' & $me_app & '" ' & $switches & ' "%1"')
        if $default then RegWrite($shell"""REG_SZ""open")

        if $reg1 and $reg2 then return true


    else ; Switch OFF..

        $regexist = RegRead($shellkey & "\command""")
        if not StringInstr($regexist$me_app) then return true

        ; okay, reg is in place, let's restore backup, if available, or delete keys..
        local $old_key1$old_key2$old_key3

        ; default command..
        if $default then
            $old_key1 = RegRead($BAX_key"")
            $old_key2 = RegRead($BAX_key"menu")
            $old_key3 = RegRead($BAX_key"cmd")

            if $old_key1 and $old_key2 and $old_key3 then

                $reg1 = RegWrite($shell"""REG_SZ"$old_key1)
                $reg2 = RegWrite($shell & "\" & $old_key1"""REG_SZ"$old_key2)
                $reg3 = RegWrite($shell & "\" & $old_key1 & "\command""""REG_SZ"$old_key3)
                if $reg1 and $reg2 and $reg3 then
                    RegDelete($BAX_key)
                    if KeyIsEmpty("HKEY_CLASSES_ROOT\" & $file_type & "\" & $my_name & "_Backup") then
                        RegDelete("HKEY_CLASSES_ROOT\" & $file_type & "\" & $my_name & "_Backup")
                    endif
                    if $old_key1 <> "open" then RegDelete($shellkey)
                    return true
                endif
            endif
        else
        ; regular menu item, simply delete it..
            $restored = RegDelete($shellkey)
            if $restored then return true
        endif
    endif

    return false
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()
                GetConceptCommands()
                KeyIsEmpty()
                ReturnAllSubkeys()
                ReturnAllValueNames()
                ReturnAllPairs()


#ce

Welcome to corz.org!

Since switching hosts (I hope you are alright, Ed! Wherever you are …) quite a few things seems to be wonky.

Juggling two energetic boys (of very different ages) on Coronavirus lockdown, I'm unlikely to have them all fixed any time soon. Mail me! to prioritise!