# BackupList.txt 语法 > 本文从 [README.md](../README.md) 拆出,单独成篇是为了让它能被单独引用与单独评审。 ```text [+|-] <软件名 或 绝对路径> [ :: <绝对路径> ] [ :- <模式>[,<模式>...] ] [ :+ <追加项>[,<追加项>...] ] [ :encrypt | :!encrypt ] [ @ ='<值>' ] [ # 说明 ] ``` 修饰符必须是**独立的、前后带空白的记号**,所以路径里出现的 `:-`、`C:\a#b` 之类不会被误切。 ### 目标(二选一) | 写法 | 说明 | | --- | --- | | `Edge` | **软件名**:去 `SoftwareCatalog.psd1` 查 Slot 组,**归档名 = 软件名** | | `C:\Programs\MiFlash` | **手写路径**:含 `\` `/` 或 `%` 就按路径处理,归档名 = `<末级名>_from_<上级路径用 + 连接>` | | `Edge @pathname` | 软件名 + 强制用路径命名(想换到名录体系但暂时不想改归档名时用) | ### 行首方向标记 | 标记 | 作用 | | --- | --- | | `+` | **仅备份,不恢复**(`Restore.ps1` 会跳过它;归档名照旧算"有主"的,不会被报成孤儿) | | `-` | **仅恢复,不备份**(`Backup.ps1` 会跳过它;适合放在别处、必要时才还原的目录) | | 无 | 既能备份也能恢复(默认) | ### 修饰符 | 修饰符 | 等价写法 | 作用 | | --- | --- | --- | | `:: <绝对路径>` | `@ Path='<绝对路径>'` | 覆盖 Path(软件名条目只有一个 Slot 时可用) | | `:- <模式>[,...]` | `@ Exclude='<模式>'` | 排除模式(`,` `;` 都当分隔符),**覆盖**名录里各 Slot 的 Exclude | | `:+ <追加项>[,...]` | `@ Include='<追加项>'` | 追加项,语法 `<归档内相对路径>:<宿主机绝对路径>`,**覆盖**名录里的 Include | | `:encrypt` | `@ Encrypt='$true'` | 该条目加密 | | `:!encrypt` | `@ Encrypt='$false'` | 该条目不加密 | | `@ ='<值>'` | — | 覆盖名录里的默认字段(目前支持 Path / Exclude / Include / Encrypt) | 兼容的历史写法仍然认:`@encrypt` / `@!encrypt` / `@pathname` / `@root=<名>`(`root=` 已废弃,只会打印告警)。 ```text # 软件名:用名录里的 Slot 与排除;再把额外目录放进包内 Modules\ 位置 Scoop :- GlobalPersist\steam\steamapps # 手写目录 + 排除 C:\Programs\MiFlash :- MiFlash\logs\ # 追加映射:把宿主机的 D:\extra\ps-modules 放到包内 Modules\ 下 PowerShell :+ Modules:D:\extra\ps-modules # 覆盖加密(名录里默认加密时特别有用) PowerShell @ Encrypt='$false' WindowsPowerShell :!encrypt ``` ### 模式(排除 / 追加)怎么写 模式匹配的是**归档内的相对路径**,而且**相对本 Slot 的根**(也就是 `\` 里面那一层): | 形态 | 展开成 | 说明 | | --- | --- | --- | | `<相对路径>` | `-x!\<相对路径>` | 锚定在归档根下这一份 | | `!<通配>` | `-xr!<通配>` | **任意层级**按组件名匹配,`*` `?` 是 7z 通配符(不是正则) | | `!re:<正则>` | 若干 `-x!<完整路径>` | **正则**:脚本自己遍历源目录把命中的路径展开成精确排除项 | | `GlobalPersist\steam` | `-x!GlobalPersist\steam` | 第一段是 Slot 名时,只作用在那一个 Slot 上 | - `!*Cache` 一次覆盖 `Cache` / `Code Cache` / `GPUCache` / `DaemonCache` 等一批以 Cache 结尾的组件名。 - 模式里**不要自己写引号**;模式里的空格会被自动转成 `?`(7z 的 `-x!` 不接受带空格的模式)。 - 想把 `.log` 之类按正则排除就写 `!re:.*\.log$`;命中的目录会整棵剪掉,命中数超过 300 条会明确报错 (命令行长度有限),这时应该改用更粗的通配模式。 - 不带 `!` 的模式是**锚定**的:Edge 的 `OneAuth\WebView2\EBWebView\` 里还有一整套自己的 `Crashpad` / `BrowserMetrics` / `ProvenanceData` / `optimization_guide`,锚定模式碰不到它们, 这些可再生的东西一律用 `!<组件名>` 才会在任意层级命中。 实测效果(本机真实 Edge 配置,源 4619.9 MB): | Edge 归档 | 大小 | 条目数 | | --- | --- | --- | | 排除规则生效前 | 1781 MB | 27961 | | 排除规则生效后 | 72 MB | 2294 | 书签、密码(`Login Data`)、`Cookies`、偏好、历史、`IndexedDB`、`Local Storage` 全部保留; 缓存、组件缓存、Service Worker、扩展本体、遥测与优化数据全部排除。 ### 行尾可以写"为什么" 行尾的 ` # 说明` 会被解析出来,运行时和 Slot 介绍一起打印: ```text Edge :- !*Cache,!Crashpad # 缓存与崩溃转储都可再生,不进归档 ``` `#` 必须前面有空白才算注释,所以路径里的 `C:\a#b` 不受影响。 ### 运行时会把每个条目的归档项逐条介绍出来 说明来自 `SoftwareCatalog.psd1` 的 Slot,追加/排除的**来源**来自清单: ```text [INFO] 条目:Scoop [INFO] 归档:Scoop.7z;方向:备份 + 恢复;加密:是 [INFO] 归档项 1/3:DefaultConfig <- C:\Users\Shuery\.config\scoop [INFO] 来源:软件名录;存在,会打包;目录 [INFO] 介绍:Scoop 配置。 [INFO] 归档项 2/3:GlobalPersist <- C:\ProgramData\scoop\persist [INFO] 来源:软件名录;存在,会打包;目录 [INFO] 排除 1 条(来自清单的 :- / @ Exclude):GlobalPersist\steam\steamapps [INFO] 排除 2 条(来自 BackupConfig.psd1 的 DefaultExcludes):!Thumbs.db、!desktop.ini ``` `Restore.ps1` 也会打印"哪一项还原到哪个目录、是文件还是目录、会新建还是覆盖"。 ### 几个必须知道的约束 - **归档名重复会直接报错。** 归档名 = 软件名字,所以同一个软件写两遍会让两个条目互相覆盖。 - **同一软件里的 Slot 名不能重复**,追加项的归档内路径也不能和 Slot 撞;脚本会在打包前明确报错。 - **一个条目挂多个归档项时,每一项只还原自己那棵子树**,不会把兄弟项也复制到别的父目录下。 - **`::` 现在是"覆盖 Path"**,不再是 `:-` 的历史别名;排除一律写 `:-`。