Python 3.X用winreg编辑Windows注册表:非HKLM根键失效问题
注册表操作代码问题排查:HKEY_CURRENT_USER等根键失效
环境与代码用途
- IDE:VS Code
- 代码主要用途:
- 编辑main.py所在目录下的文件
- 对Windows注册表执行键创建、添加描述及删除操作
原代码
import shutil import os import argparse import winreg as wrg def directory(dir_name): if (dir_name == 'HKEY_CLASSES_ROOT'): location = wrg.HKEY_CLASSES_ROOT elif (dir_name == 'HKEY_CURRENT_USER'): location = wrg.HKEY_CURRENT_USER elif (dir_name == 'HKEY_LOCAL_MACHINE'): location = wrg.HKEY_LOCAL_MACHINE elif (dir_name == 'HKEY_USERS'): location = wrg.HKEY_USERS elif (dir_name == 'HKEY_CURRENT_CONFIG'): location = wrg.HKEY_CURRENT_CONFIG return location def printf(args): file = open(file_name, "w+") file.write(text) file.close() def read(args): file = open(file_name, "r+") print(file.read()) file.close() def copy(args): shutil.move(file_name, text) def remove(args): os.remove(file_name) def create_key(args): open = wrg.OpenKeyEx(directory(register_folder), inner_reg_folder) key = wrg.CreateKey(open, file_name) if key: wrg.CloseKey(key) def print_key(args): open = wrg.OpenKeyEx(directory(register_folder), inner_reg_folder) # inner_reg_folder) key = wrg.CreateKey(open, file_name) wrg.SetValueEx(key, text, 0, wrg.REG_SZ, register_folder) if key: wrg.CloseKey(key) #print(directory(register_folder)) #print(inner_reg_folder) def del_key(args): open = wrg.OpenKeyEx(directory(register_folder), inner_reg_folder) key = wrg.CreateKey(open, file_name) del_key = wrg.DeleteKey(key, "") if key: wrg.CloseKey(key) parser = argparse.ArgumentParser() parser.add_argument('command') parser.add_argument('file_name') parser.add_argument("--text") parser.add_argument("--register_folder") parser.add_argument("--inner_reg_folder") args = parser.parse_args() command = args.command file_name = args.file_name text = args.text register_folder = args.register_folder inner_reg_folder = args.inner_reg_folder commands = { 'print': printf, 'read': read, 'copy': copy, 'remove': remove, 'create_key': create_key, 'print_key': print_key, 'delete_key': del_key } result = commands[command] result(args)
问题描述
代码使用HKEY_LOCAL_MACHINE根键时运行正常,示例命令:
python3 main.py print_key MyKey1 --text please_work --register_folder HKEY_LOCAL_MACHINE --inner_reg_folder SOFTWARE
但使用其他根键(如HKEY_CURRENT_USER)时完全失效,示例命令:
python3 main.py print_key MyKey1 --text please_work --register_folder HKEY_CURRENT_USER --inner_reg_folder Software
问题根源
- 权限缺失:调用
OpenKeyEx时未指定操作权限,默认权限无法覆盖所有根键的操作需求 - 参数逻辑错误:
print_key函数中SetValueEx的参数完全错误,将根键名称作为值数据写入,而非用户传入的text内容 - 注册表操作逻辑混乱:删除键时先创建键再删除,属于无效操作;未对异常情况做任何捕获,失败后无提示
- 资源泄漏风险:文件和注册表键的句柄未妥善管理,可能导致资源占用
修复后的代码
import shutil import os import argparse import winreg as wrg def directory(dir_name): if dir_name == 'HKEY_CLASSES_ROOT': return wrg.HKEY_CLASSES_ROOT elif dir_name == 'HKEY_CURRENT_USER': return wrg.HKEY_CURRENT_USER elif dir_name == 'HKEY_LOCAL_MACHINE': return wrg.HKEY_LOCAL_MACHINE elif dir_name == 'HKEY_USERS': return wrg.HKEY_USERS elif dir_name == 'HKEY_CURRENT_CONFIG': return wrg.HKEY_CURRENT_CONFIG raise ValueError(f"不支持的根键: {dir_name}") def printf(args): with open(args.file_name, "w+", encoding="utf-8") as file: file.write(args.text) def read(args): try: with open(args.file_name, "r+", encoding="utf-8") as file: print(file.read()) except FileNotFoundError: print(f"文件 {args.file_name} 不存在") def copy(args): try: shutil.move(args.file_name, args.text) except FileNotFoundError: print(f"源文件 {args.file_name} 不存在") except Exception as e: print(f"复制失败: {str(e)}") def remove(args): try: os.remove(args.file_name) except FileNotFoundError: print(f"文件 {args.file_name} 不存在") def create_key(args): try: root_key = directory(args.register_folder) parent_key = wrg.OpenKeyEx(root_key, args.inner_reg_folder, 0, wrg.KEY_WRITE) wrg.CreateKey(parent_key, args.file_name) wrg.CloseKey(parent_key) print(f"成功创建键: {args.register_folder}\\{args.inner_reg_folder}\\{args.file_name}") except Exception as e: print(f"创建键失败: {str(e)}") def print_key(args): try: root_key = directory(args.register_folder) parent_key = wrg.OpenKeyEx(root_key, args.inner_reg_folder, 0, wrg.KEY_WRITE | wrg.KEY_READ) key = wrg.CreateKey(parent_key, args.file_name) # 将text作为键的默认值写入,若需创建命名值可将第一个参数改为args.text wrg.SetValueEx(key, "", 0, wrg.REG_SZ, args.text) wrg.CloseKey(key) wrg.CloseKey(parent_key) print(f"成功设置键的默认值: {args.text}") except Exception as e: print(f"设置键值失败: {str(e)}") def del_key(args): try: root_key = directory(args.register_folder) parent_key = wrg.OpenKeyEx(root_key, args.inner_reg_folder, 0, wrg.KEY_WRITE) wrg.DeleteKey(parent_key, args.file_name) wrg.CloseKey(parent_key) print(f"成功删除键: {args.register_folder}\\{args.inner_reg_folder}\\{args.file_name}") except FileNotFoundError: print(f"要删除的键不存在") except Exception as e: print(f"删除键失败: {str(e)}") parser = argparse.ArgumentParser(description="文件操作与注册表管理工具") parser.add_argument('command', choices=['print', 'read', 'copy', 'remove', 'create_key', 'print_key', 'delete_key'], help="执行的命令") parser.add_argument('file_name', help="文件名或注册表键名") parser.add_argument("--text", help="文件内容、目标路径或注册表值数据") parser.add_argument("--register_folder", help="注册表根键(如HKEY_CURRENT_USER)") parser.add_argument("--inner_reg_folder", help="注册表父键路径(如Software)") args = parser.parse_args() commands = { 'print': printf, 'read': read, 'copy': copy, 'remove': remove, 'create_key': create_key, 'print_key': print_key, 'delete_key': del_key } try: commands[args.command](args) except KeyError: print("无效命令,请检查输入")
关键修改说明
- 补充权限参数:给
OpenKeyEx添加明确的读写/写入权限,确保对所有根键有合法操作权限 - 修正参数逻辑:将
print_key中SetValueEx的写入数据改为用户传入的text,符合设置键描述的需求 - 增强错误处理:添加
try-except块捕获文件和注册表操作异常,给出明确的失败提示 - 优化资源管理:用
with语句管理文件句柄,手动关闭注册表键,避免资源泄漏 - 规范参数验证:在
argparse中限制命令输入范围,避免无效命令执行
测试命令
使用HKEY_CURRENT_USER测试键值设置:
python main.py print_key MyKey1 --text "这是测试描述" --register_folder HKEY_CURRENT_USER --inner_reg_folder Software
执行后可在注册表编辑器中查看HKEY_CURRENT_USER\Software\MyKey1的默认值是否被正确设置。
内容的提问来源于stack exchange,提问作者Fillenbill
相关产品推荐
相关产品推荐

