如何递归遍历Windows注册表并获取匹配项的完整路径?
解决Windows注册表递归遍历并获取完整匹配路径的问题
核心问题分析
你的代码无法输出完整路径,原因是递归过程中没有持续追踪从根键开始的完整路径,每次递归仅传递当前子键名导致路径信息丢失;同时递归调用时传递已打开的键句柄,造成后续路径拼接逻辑错误。
修正后的代码
import winreg def scan_registry(root_key, current_subkey, key_matches, current_path=""): # 构建当前层级的完整路径 if current_path: full_path = f"{current_path}\\{current_subkey}" else: full_path = current_subkey # 初始调用时current_subkey为空,后续子键会填充路径 try: # 安全打开当前子键(自动关闭句柄) with winreg.OpenKey(root_key, current_subkey) as key: num_subkeys = winreg.QueryInfoKey(key)[0] for i in range(num_subkeys): try: subkey_name = winreg.EnumKey(key, i) # 将根键常量转换为可读字符串 root_name = { winreg.HKEY_CURRENT_USER: "HKEY_CURRENT_USER", winreg.HKEY_LOCAL_MACHINE: "HKEY_LOCAL_MACHINE", winreg.HKEY_CLASSES_ROOT: "HKEY_CLASSES_ROOT", winreg.HKEY_CURRENT_CONFIG: "HKEY_CURRENT_CONFIG", winreg.HKEY_USERS: "HKEY_USERS" }.get(root_key, "Unknown Root Key") # 检查当前子键是否匹配目标 if subkey_name == key_matches: complete_path = f"{root_name}\\{full_path}\\{subkey_name}" print(f"Found matching key: {complete_path}") # 递归遍历子键,传递更新后的完整路径 next_subkey = f"{current_subkey}\\{subkey_name}" if current_subkey else subkey_name next_path = full_path if full_path else subkey_name scan_registry(root_key, next_subkey, key_matches, next_path) except OSError: # 跳过无权限访问的子键 continue except OSError: # 跳过无权限访问的键 return # 调用示例:遍历HKEY_CURRENT_USER查找"PowerSettings" scan_registry(winreg.HKEY_CURRENT_USER, "", "PowerSettings")
关键改进点
- 完整路径追踪:新增
current_path参数,递归时持续拼接路径信息,确保能输出从根键到匹配键的完整路径。 - 根键可读转换:将winreg的根键常量映射为字符串(如
HKEY_CURRENT_USER),让输出路径更直观。 - 异常处理:添加
try-except块跳过无权限访问的注册表项,避免遍历中途中断。
扩展:返回匹配结果列表
如果需要将所有匹配路径保存为列表返回,可以修改代码如下:
import winreg def scan_registry(root_key, current_subkey, key_matches, current_path="", matches=None): if matches is None: matches = [] full_path = f"{current_path}\\{current_subkey}" if current_path else current_subkey try: with winreg.OpenKey(root_key, current_subkey) as key: num_subkeys = winreg.QueryInfoKey(key)[0] for i in range(num_subkeys): try: subkey_name = winreg.EnumKey(key, i) root_name = { winreg.HKEY_CURRENT_USER: "HKEY_CURRENT_USER", winreg.HKEY_LOCAL_MACHINE: "HKEY_LOCAL_MACHINE", winreg.HKEY_CLASSES_ROOT: "HKEY_CLASSES_ROOT", winreg.HKEY_CURRENT_CONFIG: "HKEY_CURRENT_CONFIG", winreg.HKEY_USERS: "HKEY_USERS" }.get(root_key, "Unknown Root Key") if subkey_name == key_matches: complete_path = f"{root_name}\\{full_path}\\{subkey_name}" print(f"Found matching key: {complete_path}") matches.append(complete_path) next_subkey = f"{current_subkey}\\{subkey_name}" if current_subkey else subkey_name next_path = full_path if full_path else subkey_name scan_registry(root_key, next_subkey, key_matches, next_path, matches) except OSError: continue except OSError: pass return matches # 调用并获取结果列表 results = scan_registry(winreg.HKEY_CURRENT_USER, "", "PowerSettings") print("\nAll matching paths:") for path in results: print(path)
内容的提问来源于stack exchange,提问作者cat
相关产品推荐
相关产品推荐

