9

我可以使用下面的代码从我的 Windows 7 机器注册表配置单元“HKEY_LOCAL_MACHINE”中成功检索 5 个子键。

from _winreg import *

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

我的问题是,我该如何枚举这些下的键?我想最终列出 SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Signatures\Unmanaged 文件夹中的所有密钥,但我不知道如何一步步往下走。

作为对第一条评论的回应,我在我的机器上运行了这段代码,虽然它没有出错,但它没有产生结果。

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

regedit 或 reg 查询在该文件夹中显示 6 个值,但我无法获得 python 脚本来显示这六个。

4

7 回答 7

2

只是想添加一个可能更 Pythonic 的解决方案。

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)

您现在可以按预期访问密钥

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

对于缺少suppress()的 python 版本< 3.4,我建议将其添加到您的项目中:

from contextlib import contextmanager

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

注意:如果您在读取某些值时遇到问题,则可能是从错误的注册表视图中读取。传递KEY_WOW64_64KEY或传递KEY_WOW64_32KEYflags参数)。在python 2.6OpenKey()中引入了用作上下文管理器。

于 2019-03-20T13:50:54.510 回答
1

这有效,并打印出所有子键的列表(@Broseph 答案的固定版本)

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)
于 2015-03-27T15:09:53.683 回答
1

我没有要搜索的相同注册表项,但以下代码将列出 HKEY_LOCAL_MACHINE\Software 中的所有子项。我认为如果您将 keyVal 字符串的值更改为您的目录,它将起作用。

try ... except集团是这样的,因为 EnumKey 将失败。我没有将它作为 for 循环来做,因为我不知道如何获得正确的 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
于 2013-07-02T18:56:48.813 回答
1

这样的事情有用吗?

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)
于 2013-11-22T03:12:38.067 回答
0

这只是对@sparrowt 答案的改进。当我尝试时他的答案失败了,但认为它在正确的轨道上。这将在 keypath 下方给出树。很抱歉在重写中更改了一些变量和方法名称,但只是想快速发布。在我的代码中,我将 hkey 作为全局变量 bc 我希望一次只能使用一个 hkey。

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
于 2020-11-13T17:40:25.643 回答
0

要遍历 Windows 注册表的键,您需要EnumKey()from _winregmodule. 下面给出了以下定义EnumKey():-

def EnumKey(键,索引):

  • 枚举打开的注册表项的子项。
  • key 是一个已经打开的密钥,或者任何一个预定义的 HKEY_* 常量。
  • index 是一个整数,用于标识要检索的键的索引。

请注意,此方法将索引作为参数,并且只会为您提供给定索引的键。因此,为了获取所有键,您需要将索引加一并继续,直到遇到WindowsError.

有关相同的详细了解,请参阅此帖子。代码的 Github 链接可以在帖子中找到。

于 2016-09-12T13:06:30.283 回答
0

我做了这个代码。它打印一个键的整个子树。但首先我想说的是,下面的代码并没有使用原始命名:

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

我使用以下方案

[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")

这将为您提供以下输出:

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)
        ...

于 2022-02-16T11:13:26.143 回答