LightC 如何判断卸载残留?14项信号置信度评分算法源码级解读
【免费下载链接】light-cA free, minimalist, lightweight, and high-performance C-drive cleanup tool.项目地址: https://gitcode.com/gh_mirrors/li/light-c
你是否好奇免费极简的LightC C盘清理工具是如何精准识别"卸载残留"的?它没有用粗暴的关键词匹配,而是在核心文件 leftovers.rs 中实现了一套14项信号加权置信度评分算法——每个目录都会获得一个 0.0~1.0 的分数,只有高分目录才会被标记为残留。本文带你源码级拆解这套算法的完整逻辑。
一、评分总览:为什么用"置信度"而不是"是/否"
传统清理工具通常用布尔判断:名字像不像某软件、目录在不在黑名单里。这种思路误报率高——cache、data这类通用名几乎每个软件都有。
LightC 的解决方案是加权评分模型,架构分为四层(见 leftovers.rs 开头的架构说明):
| 组件 | 作用 |
|---|---|
InstalledAppMap | 从注册表构建"已安装应用 → 路径"映射,推断目录归属 |
ScoringEngine | 对每个目录计算 0.0~1.0 的置信度分数 |
WhitelistRule | 结构化白名单(精确/前缀/通配符),保护系统目录 |
FileSystemProbe | 有限深度(4 层)文件探测.exe/.dll/ 卸载程序 |
基线分为0.0,所有分数由"正向识别加分 + 保护性降权扣分"驱动,最终通过clamp(0.0, 1.0)限制范围(ScoringContext)。
二、扫描哪里:4 条路径 + 预过滤
扫描范围由 get_scan_paths 定义:
%LOCALAPPDATA%(AppData\Local)%APPDATA%(AppData\Roaming)%LOCALAPPDATA%\..\LocalLow(模拟器残留高发地)C:\ProgramData(共享数据,谨慎处理)
在进入评分前,先做两道硬性预过滤(scan_with_paths):
- 命中白名单的目录直接跳过;
- 包名格式(
com.xxx.yyy)和纯版本号(1.2.3.4、v2.0)目录直接跳过——这类目录几乎都是框架或系统产物。
三、4 项正向信号:它们怎么加分
| 信号 | 加分 | 含义 |
|---|---|---|
| ① 发现卸载程序残留 | +0.35 | 目录内存在uninstall*.exe/uninst*.exe,软件本体已走、卸载器还在,是最强残留特征 |
| ② 匹配历史安装路径 | +0.25 | 目录名曾出现在注册表InstallLocation中,但当前注册表已找不到该应用 |
| ③ 包含可执行文件 | +0.20 | 探测到.exe/.dll等文件 |
| ④ 长期未修改 | +0.10 | 超过 7 天没有修改记录,说明软件早已不活跃 |
其中信号②依赖一个巧妙的安装历史持久化机制:每次扫描时,LightC 会把当前所有已安装应用的InstallLocation末级目录名合并进 install_history.json。这样,"以前装过、现在注册表查不到"的目录就成了残留候选——这是它能发现"干净卸载后遗留文件夹"的关键。
四、10 项负向信号:如何防止误删
正向信号决定"多像残留",负向信号决定"多可能是误报",这是评分算法的保命部分:
| 信号 | 扣分 | 保护对象 |
|---|---|---|
| ⑤ 目录名匹配已安装应用 DisplayName | -0.45 | 软件仍在用,别动 |
| ⑥ 匹配已安装应用 InstallLocation 目录 | -0.60 | 最强保护:目录明确属于在装软件 |
| ⑦ 通用目录名(cache/logs/temp/data 等 20 种) | -0.40 | 见 GENERIC_FOLDER_NAMES |
| ⑧ 位于 ProgramData | -0.30 | 系统共享目录,只降权不直接标记 |
| ⑨ 7 天内有修改记录 | -0.20 | 最近还在活动 |
| ⑩ 包名格式目录(com.xxx.yyy) | -0.15 | 预过滤的兜底 |
| ⑪ 纯版本号目录(1.2.3 / v2.0) | -0.15 | 同上 |
| ⑫ 已知共享厂商目录(Adobe、Microsoft 等 22 家) | -0.50 | 见 KNOWN_SHARED_VENDORS |
注意⑤⑥的匹配非常克制:注册表DisplayName会先经过 normalize_display_name 规范化(去版本号、去括号、转小写),且只从InstallLocation的真实目录名推断归属,不再拆分 DisplayName 的单词——源码注释明确说这是"避免短 token 碰撞导致误判"。
五、阈值分类:0.75 与 0.40 两道关卡
评分完成后,分数被映射为四类(DetectionCategory):
score ≥ 0.75 → 高置信度残留(默认推荐清理) 0.40 ≤ score < 0.75 → 可疑(仅展示,不默认勾选) score < 0.40 → 直接丢弃,不输出前端据此渲染不同颜色的分类标签,还提供"全选可疑项"按钮,让用户自行权衡(LeftoversModule.tsx)。
六、两条"短路"通道:模拟器与虚拟磁盘
有些残留无需评分,直接高置信度命中:
🎮 模拟器特征库(EMULATOR_SIGNATURES):内置雷电、蓝叠、夜神、MuMu、MEmu、MSI App Player、腾讯手游助手 7 款模拟器的文件夹关键字,命中后分数直接置为 0.90并跳过其他信号,且大小阈值从 1MB 放宽到 100KB。
💾 孤立虚拟磁盘:深度扫描会在用户目录下递归搜索.vmdk/.vdi/.vhd文件(深度 5 层,≥100MB),若父目录不属于任何已安装应用,则以0.85置信度标记。这里还有个精妙的防误报设计:WSL的ext4.vhdx路径形如\wsl\<GUID>\ext4.vhdx,直接父目录是 GUID,于是 is_path_in_whitelist 会逐级向上检查祖先目录是否命中白名单。
七、白名单:禁止"全局 contains"
白名单规则只有三种结构化类型(WhitelistRule):
Exact精确匹配:microsoft、nvidiaPrefix前缀匹配:jianyingpro*(保护剪映草稿)Pattern通配符:.*(保护所有点开头隐藏目录)
内置约 90 条规则,覆盖系统核心、显卡驱动、运行时框架、开发工具、常见应用(build_whitelist_rules)。配套的单元测试专门验证了microsoftedge不会被microsoft规则误伤——这正是"禁止 contains 模糊匹配"的价值。
此外,用户还可以把误报路径加入个人白名单(leftover_whitelist.rs),保护规则在扫描和删除两个环节都会重新校验。
八、删除前的三重安全检查
评分只负责"识别",删除环节(delete_folders)还有三道闸门:
- 白名单重校验——防止白名单更新后旧扫描结果仍被删除;白名单读取失败时直接拒绝删除,宁可多问一句;
- 路径范围校验——is_safe_leftover_path 用真实 AppData 路径前缀精确匹配,杜绝
C:\MyApp\fake\appdata这类伪装路径; - 可执行文件浅扫——目录内发现
.exe/.dll会跳过删除并提示走深度清理人工确认。
九、上手体验:在 LightC 中查看评分理由
打开 LightC 主界面的"卸载残留"模块(侧边栏即可见),点击"开始扫描"后,每个条目都会显示:
- 分类标签:高置信度 / 可疑 / 可能使用中 / 系统共享;
- 置信度百分比:鼠标悬停即可看到该目录命中的具体信号理由列表(如"包含卸载程序残留"、"已 30 天未修改");
- 一键加入白名单:对误报条目点击盾牌图标即可永久保护。
前端展示逻辑见 LeftoversModule.tsx,Tauri 命令入口在 commands/leftovers.rs。
十、总结:这套算法好在哪
✅可解释:每个分数都有中文理由,用户看得见"为什么被判为残留"; ✅双保险:正向信号抓真残留,负向信号 + 白名单防误删; ✅动态学习:安装历史缓存让它能记住"曾经装过"的软件; ✅删除克制:三重检查 + 白名单失效即拒删,安全边界清晰。
一次扫描的完整流程:白名单过滤 → 预过滤 → 模拟器短路 → 文件探测 → 14项信号评分 → 阈值分级 → 排序输出,全部封装在 LeftoverScanner::scan 中。想深入源码的读者,建议从该函数和文件开头的 架构注释 读起。
【免费下载链接】light-cA free, minimalist, lightweight, and high-performance C-drive cleanup tool.项目地址: https://gitcode.com/gh_mirrors/li/light-c
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考