Search code examples
pythonwinreg

Python - Winreg get key values


I am trying to work with WinReg in Python, but I am facing an obstacle. The following code is supposed to return a dictionary with a key:value for each returned entry, I find myself getting the same key:value.

How I can edit this code to get a different value or values?

import _winreg
def subkeys(key):
    i = 0
    while True:
        try:
            subkey = _winreg.EnumKey(key, i)
            yield subkey
            i+=1
        except WindowsError as e:
            break

def traverse_registry_tree(hkey, keypath, tabs=0):
    reg_dict = {}
    key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ)
    for subkeyname in subkeys(key):
        reg_dict[subkeyname] = subkeyname
    return reg_dict

keypath = r"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"

print traverse_registry_tree(_winreg.HKEY_LOCAL_MACHINE, keypath)

The output is something similar to this :

{'Mozilla Firefox 40.0.2 (x86 en-US)': 'Mozilla Firefox 40.0.2 (x86 en-US)', 'IE40': 'IE40', 'Connection Manager': 'Connection Manager'}

Any help will be appreciate, please keep in mind I am not in anyway an advanced pythonist.


Solution

  • Each time you recurse into your traverse_registry_tree function you create a new dictionary. So each dictionary only ever has one key in it.

    You can kind of tell this is wrong because in the recursive call you don't do anything with the return value: the outside call prints the return but the inside call doesn't.

    You could fix this by packing the return value from the recursive call back into the dictionary you are creating. But that's not as efficient as just passing the whole dictionary in and out of the recursive call:

    def traverse_registry_tree(hkey, keypath, reg_dict):
        key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ)
        reg_dict[keypath] = key
        for subkey in subkeys(key):
            subkeypath = "%s\\%s" % (keypath, subkey)
            traverse_registry_tree(hkey, subkeypath, reg_dict)
    
    reg_dict = {}
    keypath = r"SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall"
    traverse_registry_tree(_winreg.HKEY_LOCAL_MACHINE, keypath, reg_dict)
    
    print(reg_dict)
    

    Not sure if you are also asking how to access registry values (as well as the keys)? If so, here is some code to do that too:

    def get_values(key):
        key_dict = {}
        i = 0
        while True:
            try:
                subvalue = _winreg.EnumValue(key, i)
            except WindowsError as e:
                break
            key_dict[subvalue[0]] = subvalue[1:]
            i+=1
        return key_dict
    
    def traverse_registry_tree(hkey, keypath, reg_dict):
        key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ)
        reg_dict[keypath] = get_values(key)
        for subkey in subkeys(key):
            subkeypath = "%s\\%s" % (keypath, subkey)
            traverse_registry_tree(hkey, subkeypath, reg_dict)