重构为可核对、可恢复的备份工具(P0-P3)

修复(P0)
- 退出码:改用 .NET Process 继承控制台启动外部命令。Start-Process -PassThru 的
  ExitCode 在 PowerShell 7.7.0-preview.4 上恒为 $null,会把成功的压缩判成失败,
  并让 "exit 2 -> 删档重试" 的自愈分支永远不可达。
- BackupList.txt 解析:先按第一个 :: 切开再处理引号,修正整行被引号包住时
  排除表被吞进路径的问题(该条目此前被静默跳过,其 2.8 GB 归档成了孤儿)。
- 排除分隔符同时接受 , 与 ;:此前解析器只认 ; 而清单里写的是 ,,
  等于所有排除规则都没生效。
- 7z 排除参数不再嵌引号,含空格的模式自动转成 ?:旧写法 -x!"路径" 会让引号
  成为模式的一部分,导致排除对所有条目都失效。

加固(P1)
- 先写临时归档 -> 7z t 校验 -> 原子替换,中断不再污染正式归档。
- 放弃 7z 的更新模式 u:固实压缩下收益极小,却让排除规则改动与已删文件
  永远进不了归档。
- 新增 Backups/manifest.json 与 logs/*.log,跳过/失败有据可查。
- 结尾按失败数 exit;恢复支持 -WhatIf / -DryRun / -VerifyOnly / -Only。
- 恢复优先用 manifest 定位归档,并精确比较 BaseName(不再用 -Filter 通配)。
- 修正 tar 分支用 $LASTEXITCODE 判断成功与否的缺陷。
- 有警告(文件被占用)时拒绝用不完整的归档覆盖完整归档,需显式 -AcceptWarnings。

策略与安全(P2)
- Edge 条目加排除规则:解压后 4.22 GB 中 3.79 GB 是可再生的缓存/遥测/扩展本体,
  保留书签、密码、偏好、历史与站点数据。
- 可选 7z 加密(@encrypt 标记或全局开关),取不到口令时明确失败,绝不写明文。
- 磁盘空间守卫:放不下就跳过该条目,低于阈值告警。

工程化(P3)
- 新增 BackupConfig.psd1、README.md、.gitignore。
- tests/Run-Tests.ps1(32 项)与 tests/Run-E2E.ps1(16 项端到端验收)。
- tools/Register-BackupTask.ps1 注册每日计划任务。
- 归档命名算法保持不变,已有归档不会失联。
This commit is contained in:
Shuery committed 2026-09-21 20:10:18 +08:00
commit dbc0c00554
11 files changed
+2934

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
# BackupList.txt —— 备份 / 恢复共用清单
#
# 语法:
# <路径> [ :: <排除模式>[,<排除模式>...] ] [ @<标记> ]
#
# 路径 :支持 %环境变量%;可用双引号包裹(引号只包路径);/ 与 \ 等价。
# 排除模式 :相对归档根目录(也就是源目录的末级名)。
# 以 ! 开头表示"任意层级下匹配这个组件名",翻译成 7z 的 -xr!。
# 不要自己写引号;7z 的模式不支持空格,工具会自动把空格转成 ?。
# 标记 :encrypt = 用 7z 加密这个归档(口令来自 BAKNRET_PASSWORD 或 -KeyFile)。
#
# 注意:
# * 归档名由 <末级名>_from_<上级路径用 + 连接> 生成。改动路径会生成新归档名,
# 旧归档不会被自动迁移,恢复时请用 manifest.json 或保留原写法。
# * 源路径不存在的条目会明确报告为「跳过: 路径不存在」,不再静默忽略。
# * 对已经不存在、但归档还在的条目,保留在这里可以继续恢复出历史数据。
# ---- 用户配置 / 开发环境 ----
%UserProfile%/.config/legendary
%UserProfile%/.config/scoop
%UserProfile%/.ssh
# 想加密 .ssh(内含私钥)就改成下面这行,并先配置好口令,见 README「加密」一节:
# %UserProfile%/.ssh @encrypt
%UserProfile%\Documents\CodeSpace :: Shuery-Shuai\ImmortalWrt-BPI-R4-Firmware\immortalwrt\
%UserProfile%\Documents\PowerShell
%UserProfile%\Documents\WindowsPowerShell
%UserProfile%/scoop/persist
# ---- 应用数据 ----
%AppData%\AutoDarkMode
%AppData%/com.example/Kazumi
%AppData%/com.example/piliplus
%AppData%\fnm
%AppData%/twinkle-tray
# ---- 浏览器:排除可再生的缓存、遥测与扩展本体 ----
# 解压后 4.22 GB / 25030 个文件里,下面这组排除会留下约 431 MB / 2164 个文件,
# 排除掉的 3.79 GB 全部可以重新生成:缓存、组件缓存、Service Worker、
# 扩展本体(可从商店重装)、遥测与优化数据。
# 书签/密码/偏好/历史,以及站点数据(IndexedDB / Local Storage)都保留。
# 想再省 230 MB,可以把 Default\IndexedDB、Default\Local Storage、
# Default\Session Storage、Default\blob_storage、Default\WebStorage 也加进排除表。
# !*Cache 表示"任意层级下以 Cache 结尾的目录",能一次覆盖 Cache / Code Cache /
# GPUCache / DawnCache / GrShaderCache / ShaderCache 等一批。模式里的空格会被
# 自动转成 ?(7z 的排除模式不支持空格)。
%LocalAppData%\Microsoft\Edge\User Data :: !*Cache,component_crx_cache,Default\Service Worker,Default\Extensions,Default\ExtensionActivityEdge,ProvenanceData,optimization_guide,Crashpad,BrowserMetrics,Snapshots,Edge Sidebar,Edge Shopping
%LocalAppData%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json
# ---- 系统 ----
%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup
# ---- C:\Programs ----
C:\Programs\BaiduNetdisk
C:\Programs\FooClolor
C:\Programs\March7thAssistant :: 3rdparty\WebBrowser\UserProfile\Integrated,March7thAssistant\logs\
C:\Programs\MiFlash
C:\Programs\MiFlash_Unlock
C:\Programs\QuarkCloudDrive
C:\Programs\ScoopApps\apps\translucenttb\current\settings.json
C:\Programs\ScoopApps\persist :: persist\ariang-native\UserData\DawnCache,persist\ariang-native\UserData\GPUCache,persist\ariang-native\UserData\Local Storage,persist\ariang-native\UserData\Session Storage
# ---- 其它盘 ----
D:\UserData\Documents\Aria
D:\UserData\Documents\CodeSpace
E:\CodeSpace