Python winreg looping through sub-keys

前端 未结 6 1383
悲哀的现实
悲哀的现实 2021-01-12 05:16

I\'m able to successfully retrieve the 5 sub-keys from my windows 7 machine registry hive \"HKEY_LOCAL_MACHINE\" with the code below.

from _winreg import *

         


        
相关标签:
6条回答
  • 2021-01-12 05:29

    For iterating through keys of Windows registry, you would need EnumKey() from _winreg module. Given below is the definition for EnumKey() :-

    def EnumKey(key, index):

    • Enumerates subkeys of an open registry key.
    • key is an already open key, or any one of the predefined HKEY_* constants.
    • index is an integer that identifies the index of the key to retrieve.

    Note that this method, takes index as an argument, and will provide you the key only for the given index. Therefore, in order to get all the keys, you need to increment the index by one and continue until you encounter WindowsError.

    Refer to this post for a detailed understanding on the same. The Github link for the code can be found in the post.

    0 讨论(0)
  • 2021-01-12 05:31

    I don't have the same registry keys to search but the following code will list all the subkeys in HKEY_LOCAL_MACHINE\Software. I think if you change the value of the keyVal string to your directory it will work.

    The try ... except bloc is this way because EnumKey will fail. I didn't do it as a for loop because I dont know how to get the correct length of aKey.

    keyVal = r"Software"
    aKey = OpenKey(HKEY_LOCAL_MACHINE, keyVal, 0, KEY_ALL_ACCESS)
    try:
        i = 0
        while True:
            asubkey = EnumKey(aKey, i)
            print(asubkey)
            i += 1
    except WindowsError:
        pass
    
    0 讨论(0)
  • 2021-01-12 05:34

    Just want to add a perhaps more pythonic solution.

    from _winreg import *
    from contextlib import suppress
    import itertools
    
    def subkeys(path, hkey=HKEY_LOCAL_MACHINE, flags=0):
        with suppress(WindowsError), OpenKey(hkey, path, 0, KEY_READ|flags) as k:
            for i in itertools.count():
                yield EnumKey(k, i)
    

    You can now access the keys as expected

    for key in subkeys(r'path\to\your\key'):
        print key
    

    For python versions < 3.4 that lack suppress(), I recommend adding it to your project:

    from contextlib import contextmanager
    
    @contextmanager
    def suppress(*exceptions):
        try:
            yield
        except exceptions:
            pass
    

    Note: If you have trouble reading some values you might be reading from the wrong registry view. Pass KEY_WOW64_64KEY or KEY_WOW64_32KEY to the flags parameter). Using OpenKey() as context manager was introduced in python 2.6.

    0 讨论(0)
  • 2021-01-12 05:35

    Does something like this work?

    import _winreg
    
    def subkeys(key):
        i = 0
        while True:
            try:
                subkey = _winreg.EnumKey(key, i)
                yield subkey
                i+=1
            except WindowsError:
                break
    
    def traverse_registry_tree(key=_winreg.HKEY_LOCAL_MACHINE, tabs=0):
        for k in subkeys(key):
            print '\t'*tabs + str(k)
            traverse_registry_tree(k, tabs+1)
    
    0 讨论(0)
  • 2021-01-12 05:37

    this is just an improvement on @sparrowt's answer. His answer failed when I tried it, but think it was on the right track. This will give tree below keypath. Sorry for changing some variable and method names in rewrite, but just trying to post this quick. In my code, I put hkey as global variable bc I expect to only be working with one hkey at a time.

    import winreg
    import itertools
    hkey = winreg.HKEY_LOCAL_MACHINE
    def list_subkeys(path, hkey_set=None):
        global hkey
        if not hkey_set:
            hkey_set = hkey
        try:
            registry_key = winreg.OpenKey(hkey_set, path, 0, winreg.KEY_READ)
            for i in itertools.count():
                yield winreg.EnumKey(registry_key, i)
            winreg.CloseKey(registry_key)
        except Exception as ex:
            if str(ex) != '[WinError 259] No more data is available':
                print(str(ex))
            try:
                winreg.CloseKey(registry_key)
            except:
                pass
            return []
    
    def traverse_registry_tree(keypath, levels=None, hkey_set=None):
        global hkey
        if not levels:
            levels = []
        if not hkey_set:
            hkey_set = hkey
        subkeys = list(list_subkeys(keypath, hkey_set))
        for subkeyname in subkeys:
            subkeypath = "%s\\%s" % (keypath, subkeyname)
            levels.append(subkeypath)
            levels.extend([r for r in traverse_registry_tree(subkeypath, levels, hkey_set) if r not in levels])
        del subkeys
        return levels
    
    0 讨论(0)
  • 2021-01-12 05:44

    This works, and prints out the list of all subkeys (fixed version of @Broseph's answer)

    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):
        key = _winreg.OpenKey(hkey, keypath, 0, _winreg.KEY_READ)
        for subkeyname in subkeys(key):
            print '\t'*tabs + subkeyname
            subkeypath = "%s\\%s" % (keypath, subkeyname)
            traverse_registry_tree(hkey, subkeypath, tabs+1)
    
    keypath = r"SOFTWARE\\Microsoft\\Windows"
    
    traverse_registry_tree(_winreg.HKEY_LOCAL_MACHINE, keypath)
    
    0 讨论(0)
提交回复
热议问题