# SoftwareCatalog.psd1 —— 软件名 → Slot 组 > 本文从 [README.md](../README.md) 拆出,单独成篇是为了让它能被单独引用与单独评审。 ```powershell @{ Edge = @{ # Slot = 归档内的一层目录:内容进 DefaultData\,恢复时整棵回到这个 Path DefaultData = @{ Path = '%LocalAppData%\Microsoft\Edge\User Data' Exclude = '!*Cache,!Crashpad,Default\Extensions,Default\Service Worker' Description = 'Edge 用户数据:书签/密码/偏好/历史,以及站点数据' } } Scoop = @{ # 一个软件可以有多个 Slot;两个都叫 persist 的目录因此不再冲突 DefaultConfig = @{ Path = '%UserProfile%\.config\scoop' Encrypt = $true Description = 'scoop 自身的配置' } UserPersist = @{ Path = '$(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE "scoop" })\persist' Encrypt = $true Description = 'scoop 各应用的持久化数据' } } WindowsTerminal = @{ # Path 指向文件时,归档里就是一个名为 DefaultData 的文件(没有扩展名) DefaultData = @{ Path = '%LocalAppData%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json' Encrypt = $true Description = 'Windows Terminal 的设置文件' } } } ``` 字段: | 字段 | 说明 | | --- | --- | | Slot 名 | **归档内的一层目录**。内容进 `\`;Path 是文件时就是名为 `` 的文件。同一软件里不能重名 | | `Path` | 宿主机上的绝对路径。支持 `%变量%` 与 `$( ... )` 子表达式 | | `Exclude` | 排除模式,相对本 Slot 的根,逗号分隔。`!` 打头 = 任意层级(7z 通配符),`!re:<正则>` = 正则 | | `Include` | 追加项,`<归档内相对路径>:<宿主机绝对路径>`,逗号分隔 | | `Encrypt` | 该归档是否加密,默认 `$false`。同一软件里若各 Slot 不一致,整个归档按**加密**处理 | | `Description` | 这个 Slot 是干什么的;运行时逐条打印 | 要点: - **`Path` 支持 `$( ... )`**:`$(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE "scoop" })` 会按 PowerShell 求值(求值结果会缓存,不会每个条目重复起进程)。 这类写法用了 `+` 拼接字符串时,`Import-PowerShellDataFile` 会拒绝,脚本会自动改用 PowerShell 求值——名录与配置是仓库里的本地文件,和脚本同级,信任级别相同。 - **目录当前不存在也不会被丢掉**:备份时跳过并记 `missing-source`,但恢复时仍然知道 "这块内容原本该回到哪个位置",这正是恢复要用的。 - **前缀补全**:写 `D:\Programs\legendary`,实际目录是 `legendary_2.0.4` 时会自动匹配 (只认 `<名>_*` 与 `<名>-*`)。一个 Slot 只能对应一个目录,补全出多个会明确报错并让你拆 Slot。 - **一个软件里不能有两个同名 Slot**,否则归档内会混成一棵树;脚本会明确报错。 **分文件维护**:用 `Includes` 引入其它名录文件(路径相对本文件): ```powershell @{ Includes = @('SoftwareCatalog.games.psd1') ... } ```