9

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 *

try:
    i = 0
    while True:
        subkey = EnumKey(HKEY_LOCAL_MACHINE, i)
        print subkey
        i += 1
except WindowsError:
    pass

My question is, how do I then enumerate the keys under those? I want to end up listing all the keys in the SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged folder but I can't figure out how to step my way down there.

In response to the first comment, I ran this code on my machine and while it didn't error out, it didn't produce results.

from _winreg import *

aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
aKey = OpenKey(aReg, r"SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged")
for i in range(1024):
    try:
        keyname = EnumKey(aKey, i)
        asubkey = OpenKey(aKey, keyname)
        val = QueryValueEx(asubkey, "Description")
        print val
    except WindowsError:
        break

A regedit or reg query shows 6 values in that folder but I can't get a python script to show me those six.

davelupt
  • 1,845
  • 4
  • 21
  • 32
user1982218
  • 91
  • 1
  • 1
  • 3

7 Answers7

2

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.

Nuno André
  • 4,739
  • 1
  • 33
  • 46
wihlke
  • 2,455
  • 1
  • 19
  • 18
1

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
1

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)
Broseph
  • 1,655
  • 1
  • 18
  • 38
  • No because `EnumKey` returns a string which you then try and pass in as a `PyHKEY` which doesn't work – sparrowt Mar 27 '15 at 15:03
1

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)
sparrowt
  • 2,641
  • 25
  • 24
  • Within traverse_registry_tree(hkey, keypath, tabs=0), the call traverse_registry_tree(subkeypath, tabs+1) seems to omit the first argument, which should be hkey, I think. – gwideman Apr 16 '15 at 08:57
0

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.

Community
  • 1
  • 1
Pabitra Pati
  • 457
  • 4
  • 12
0

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

I made this code. It prints the whole subtree of a key. But first, I would like to say that the following code does not use the original naming:

[key]
  |-[key]
  |   └-[value1: data]
  |-[value1: data]
  └-[value2: data]

I use the following scheme

[folder]
  |-[subfolder]
  |   └-[key1: value]
  |-[key1: value]
  └-[key2: value]
import winreg
def padding(cnt):
    str = ""
    for i in range(cnt):
        str += '\t'
    return str

def recursive_visit(folder, i):
    subfolders_count, subkeys_count, modified = winreg.QueryInfoKey(folder)
    for subfolder_index in range(subfolders_count):
        try:
            subfolder_name = winreg.EnumKey(folder, subfolder_index)
            print(padding(i)+subfolder_name+":")
            with winreg.OpenKeyEx(folder, subfolder_name) as subfolder:
                recursive_visit(subfolder, i+1)
        except (WindowsError, KeyError, ValueError):
            print("Error reading " + folder)
    for subkey_index in range(subkeys_count):
        print(padding(i)+str(winreg.EnumValue(folder, subkey_index)))
        globals()["cnt"] += 1

cnt = 0 #how many keys we visited

### ENTER INPUT HERE
root = winreg.HKEY_LOCAL_MACHINE
folder = r"SYSTEM\Setup\FirstBoot\Services"
###

with winreg.OpenKey(root, folder) as reg:
    keys_count, values_count, modified = winreg.QueryInfoKey(reg)
    print("Subfolders: " + str(keys_count) + " Subkeys: " + str(values_count))
    recursive_visit(reg, 1)
print("visited " + str(cnt) + " leaf keys")

This gives you the following output:

Subkeys: 72 Subvalues: 1
    AdobeARMservice:
        ('ServiceName', 'AdobeARMservice', 1)
        ('Path', '"C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\armsvc.exe"', 1)
        ('Path.Org', '"C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\armsvc.exe"', 1)
        ('Path.Win32', 'C:\\Program Files (x86)\\Common Files\\Adobe\\ARM\\1.0\\armsvc.exe', 1)
        ('StartName', 'LocalSystem', 1)
        ('DisplayName', 'Adobe Acrobat Update Service', 1)
        ('Type', 16, 4)
        ('StartType', 2, 4)
        ('ErrorControl', 0, 4)
        ('LoadOrderGroup', '', 1)
        ('TagId', 0, 4)
    AdobeUpdateService:
        ('ServiceName', 'AdobeUpdateService', 1)
        ...

Patrik Staron
  • 331
  • 1
  • 9