手搓一个 Windows 注册表清理器:从开发到 EXE 打包全流程

在这里插入图片描述

📅 前言

相信大家在使用 Windows 时都遇到过这种情况:直接删除了软件安装目录,或者卸载过程出错,导致“设置 -> 应用和功能”列表里依然残留着软件的图标。点击卸载,系统只会弹窗提示“找不到文件”,看着非常难受(强迫症噩梦)。

虽然市面上有各种管家类软件,但为了这点小功能装个大管家实在没必要。作为开发者,不如利用 Python 自己动手写一个轻量级的清理工具。

本文将复盘整个开发过程,包括 注册表扫描UAC 管理员提权Tkinter UI 美化 以及最终的 PyInstaller 打包

🔗 项目源码

本项目已开源至 Gitee,欢迎 Star 和 Fork!

🛠️ 核心思路

Windows 的“添加/删除程序”列表,本质上是读取注册表中的特定路径。我们需要做的就是:

  1. 扫描:遍历 HKCU (当前用户) 和 HKLM (本地机器) 下的 Uninstall 注册表项。
  2. 判断:读取每个软件的 InstallLocation (安装路径),检测该路径在磁盘上是否存在。如果不存在,判定为“失效”。
  3. 展示:通过 GUI 列表展示失效项,供用户勾选。
  4. 清理:调用 Windows API 删除选中的注册表项。

💻 实现细节

1. 注册表扫描 (winreg)

Python 自带的 winreg 模块足以应对。我们需要关注的路径通常是:
Software\Microsoft\Windows\CurrentVersion\Uninstall

import winreg
import os

# 扫描逻辑简化版
def scan():
    scan_locations = [
        (winreg.HKEY_CURRENT_USER, r"Software\Microsoft\Windows\CurrentVersion\Uninstall"),
        (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall"),
        # 还要注意 64位系统下的 32位应用注册表
        (winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall")
    ]
    
    for hive, subkey in scan_locations:
        # ... 遍历 EnumKey ...
        # 读取 InstallLocation 并使用 os.path.exists 判断

2. 搞定管理员权限 (UAC)

要删除 HKEY_LOCAL_MACHINE 下的内容,必须拥有管理员权限。

为了体验更好,我实现了自动提权:程序启动时检测是否为 Admin,如果不是,则通过 ShellExecuteW 重新以管理员身份启动自己。

这里有个坑:脚本运行打包后的 EXE 运行,提权参数是不一样的。

import ctypes
import sys

def is_admin():
    try:
        return ctypes.windll.shell32.IsUserAnAdmin()
    except:
        return False

if __name__ == "__main__":
    if is_admin():
        # 启动主程序 UI
        root = tk.Tk()
        app = RegistryCleanerApp(root)
        root.mainloop()
    else:
        # 请求提权
        try:
            if getattr(sys, 'frozen', False):
                # 如果是打包后的 exe
                script_param = None
            else:
                # 如果是 .py 脚本
                script_param = f'"{__file__}"'

            ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, script_param, None, 1)
            sys.exit()
        except Exception as e:
            print(f"Failed to elevate: {e}")

3. UI 交互与美化 (Tkinter + Pillow)

原生 Tkinter 的 Checkbutton 在 Treeview (列表控件) 中支持得并不好,而且在高分屏下非常小,难以点击。

解决方案:使用 Pillow 库动态绘制 24x24 像素的图片(选中/未选中状态),放入 Treeview 的第一列,模拟复选框。

from PIL import Image, ImageDraw, ImageTk

def create_checkbox_icons(self):
    size = 24
    # 绘制未选中方框
    img_un = Image.new('RGBA', (size, size), (0, 0, 0, 0))
    draw_un = ImageDraw.Draw(img_un)
    draw_un.rectangle([2, 2, size-3, size-3], outline='#555555', width=2, fill='#FFFFFF')
    self.icon_unchecked = ImageTk.PhotoImage(img_un)

    # 绘制选中方框 (蓝色背景 + 白色对勾)
    img_chk = Image.new('RGBA', (size, size), (0, 0, 0, 0))
    draw_chk = ImageDraw.Draw(img_chk)
    draw_chk.rectangle([2, 2, size-3, size-3], outline='#0078D7', width=2, fill='#0078D7')
    # ... 画对勾逻辑 ...
    self.icon_checked = ImageTk.PhotoImage(img_chk)

这样不仅解决了点击区域过小的问题,还让界面看起来更像现代的 Win11 风格。

4. 项目结构工程化

为了避免项目杂乱,我将源码和资源进行了分离:

regeditClean/
├── src/                  # 源代码 (main.py 等)
├── assets/               # 资源文件 (图标、版本信息、截图)
├── build_config/         # PyInstaller 配置目录
├── dist/                 # 最终 EXE 输出
└── requirements.txt      # 依赖库

📦 PyInstaller 打包

最后一步是将 Python 脚本打包成独立的 .exe,方便在没有 Python 环境的电脑上使用。

为了让 EXE 看起来更正规,我做了以下几点:

  1. 自定义图标:生成了一个 .ico 文件。
  2. 版本信息:创建 file_version_info.txt,写入版权和版本号。
  3. 配置文件分离:将 .spec 文件生成到 build_config 目录,保持根目录整洁。

打包命令:

pyinstaller --noconsole --onefile ^
    --name="RegCleanTool" ^
    --icon="assets\app_icon.ico" ^
    --version-file="assets\file_version_info.txt" ^
    --specpath="build_config" ^
    --distpath="dist" ^
    --workpath="build" ^
    src\main.py

🧪 安全测试

为了验证工具的可靠性,绝对不能拿自己的系统注册表开玩笑。

我编写了一个 create_test_entry.py 脚本,专门在 HKCU 下生成 5 个指向假路径的注册表项(例如指向 C:\Game\Ghost.exe)。通过“生成假数据 -> 扫描 -> 清理 -> 验证”的闭环测试,确保了工具逻辑的严密性。

🎉 最终效果

(这里可以插入您的运行截图 assets/runtime.png)

工具完美运行,成功识别并清理了测试生成的失效项,且 UI 清晰易用。


如果你觉得这个小工具对你有帮助,或者想研究下源码,欢迎访问我的 Gitee 仓库:
👉 https://gitee.com/sen2020/regedit-clean


标签: Python, Tkinter, 注册表清理, PyInstaller, 开源工具, Windows开发

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

森叶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值