Python删除注册表键及其子项

Python中可以使用winreg模块中的DeleteKey方法来删除注册表中的键,但该方法不能删除包含子键的键。所以,在删除某个键时要先删除它的所有子键,这里借助栈结构通过循环迭代的方式来获取注册表键的所有子键及子键的子键。完整代码如下:

 

# 注册表相关

# import os
#
# print(os.getlogin())
#
# import ctypes
#
# if not ctypes.windll.shell32.IsUserAnAdmin():
#     raise PermissionError("非管理员权限")

import winreg

from loguru import logger

from simple_stack import SimpleStack
from src.config.app_options import options


class RegCleaner:
    """注册表数据清理"""

    # 注册表键不存在子键错误码
    # https://bugs.python.org/file7326/winerror.py
    _ERROR_NO_MORE_ITEMS = 259

    def __init__(self):
        self._key_stack = SimpleStack()
        root_key = options.ppt.registry_key_name
        self._key_stack.push(root_key)
        self._key_name_stack = SimpleStack()

    @staticmethod
    def _open_registry(key_name):
        key = winreg.OpenKey(winreg.HKEY_CURRENT_USER
                             , key_name
                             , reserved=0
                             , access=winreg.KEY_ALL_ACCESS)
        return key

    def _get_sub_keys(self):
        """获取键的所有直接子键"""
        i = 0
        key_name = self._key_stack.pop()
        if key_name is None:
            return
        key: winreg.HKEYType | None = None
        try:
            key = self._open_registry(key_name)
            while True:
                sub_key = winreg.EnumKey(key, i)
                sub_key_name = fr"{key_name}\{sub_key}"
                self._key_stack.push(sub_key_name)
                self._key_name_stack.push(sub_key_name)
                i += 1
        except OSError as err:
            if err.winerror != self._ERROR_NO_MORE_ITEMS:
                logger.exception("获取注册表键异常:{err}", err=err)
        finally:
            if key:
                key.Close()

    def del_registry_key(self):
        """删除注册表中的键"""

        # 迭代获取键的所有子键及子键的子键
        while len(self._key_stack) > 0:
            self._get_sub_keys()

        key_name = self._key_name_stack.pop()
        while key_name is not None:
            key: winreg.HKEYType | None = None
            try:
                key = self._open_registry(key_name)
                winreg.DeleteKey(key, "")
                logger.info("已删除注册表键:{key_name}", key_name=key_name)
            except Exception as err:
                logger.exception("删除注册表键异常:{err}", err=err)
            finally:
                if key:
                    key.Close()
            key_name = self._key_name_stack.pop()

 

⚠️ 需用管理员权限来运行脚本

posted @ 2023-06-19 15:52  雪飞鸿  阅读(244)  评论(0编辑  收藏  举报