前言
相信大家在使用 windows 时都遇到过这种情况:直接删除了软件安装目录,或者卸载过程出错,导致“设置 -> 应用和功能”列表里依然残留着软件的图标。点击卸载,系统只会弹窗提示“找不到文件”,看着非常难受(强迫症噩梦)。
虽然市面上有各种管家类软件,但为了这点小功能装个大管家实在没必要。作为开发者,不如利用 python 自己动手写一个轻量级的清理工具。
本文将复盘整个开发过程,包括 注册表扫描、uac 管理员提权、tkinter ui 美化 以及最终的 pyinstaller 打包。
项目源码
本项目已开源至 gitee,欢迎 star 和 fork!
gitee 地址:https://gitee.com/sen2020/regedit-clean
核心思路
windows 的“添加/删除程序”列表,本质上是读取注册表中的特定路径。我们需要做的就是:
- 扫描:遍历
hkcu(当前用户) 和hklm(本地机器) 下的uninstall注册表项。 - 判断:读取每个软件的
installlocation(安装路径),检测该路径在磁盘上是否存在。如果不存在,判定为“失效”。 - 展示:通过 gui 列表展示失效项,供用户勾选。
- 清理:调用 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 看起来更正规,我做了以下几点:
- 自定义图标:生成了一个
.ico文件。 - 版本信息:创建
file_version_info.txt,写入版权和版本号。 - 配置文件分离:将
.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 清晰易用。
到此这篇关于使用python手搓一个windows注册表清理器的文章就介绍到这了,更多相关python windows注册表清理器内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论