Files
BakNRet/BakNRet/BakNRet.psm1
T
Shuery effc38fdd3 feat(tui): 名录编辑器循环 + 挂进 Edit-Config(第三轮第二块·完成)
装配:Get-BakNRetCatalogField → 菜单选字段 → Read-BakNRetLine → Set-BakNRetCatalogField → Save-BakNRetConfigFile(校验通过才原子替换 + 时间戳备份)。

菜单里**只列可编辑的字段**(单行的 Encrypt / Description):把只读的 Path / Exclude 也列出来再拒绝,会让每个只读项浪费用户一次回车。

校验用模块自己的 Import-BaknretDataFile:这份名录有 $( ) 动态表达式与跨行拼接,普通数据文件读取器读不了 —— 而正是它保证"改完整份文件还能被程序读回来"(值能读回来才算改成功)。定位用 (软件名, Slot, 字段名) 三元组,因为同一软件可以有多个 Slot。

Edit-Config 的三个界面(清单 / 设置 / 名录)至此全部完成。

判据 9 条:改一个值后只动一行、注释行数不变、改完能读回新值、留下时间戳备份且备份里是原文;取消时不写盘也不产生备份。

验收:test.ps1 9/9 全绿(5.1 与 7);真实清单只读冒烟 4/4。
2026-09-27 21:30:14 +08:00

275 lines
11 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
.SYNOPSIS
BakNRet —— 备份 / 恢复脚本的公共功能模块。
.DESCRIPTION
提供日志(控制台 + 落盘)、外部命令调用(可取得真实退出码)、
BackupList.txt 语法解析、归档命名与逆向解析、目录摘要、manifest 读写、
磁盘剩余空间查询等公共能力。
兼容 Windows PowerShell 5.1 与 PowerShell 7.x:
* 不使用 ?? / 三元运算符 / Join-String / -AsHashtable 等 6.0+ 语法;
* 不使用 ProcessStartInfo.ArgumentList(5.1 上不存在),改为自行构造命令行。
模块内出现的备份清单语法(BackupList.txt 每一行):
[+|-] <软件名 或 绝对路径> [修饰符...] [# 说明]
[:: <Absolute\Path>] [:- <模式>[,...]] [:+ <包含项>[,...]]
[:encrypt | :!encrypt] [@ <Key>='<Value>']
标记(必须是独立的空白分隔记号,前后都要有空格):
+ 仅备份,不恢复(Restore.ps1 跳过)
- 仅恢复,不备份(Backup.ps1 跳过)
:: 覆盖 Path,等价于 `@ Path='...'`
:- 排除模式,等价于 `@ Exclude='...'`
:+ 追加包含项(<归档内相对路径>:<宿主机绝对路径>),等价于 `@ Include='...'`
:encrypt 该条目加密(`@ Encrypt='$true'`)
:!encrypt 该条目不加密(`@ Encrypt='$false'`)
@ Key='值' 覆盖 SoftwareCatalog.psd1 里的同名默认字段
兼容的历史写法:`@encrypt` / `@!encrypt` / `@pathname` / `@root=<名>`,
以及用双引号包住路径或模式值。
归档内布局(SoftwareCatalog.psd1 的 Slot 是包内的一层目录):
软件名条目 -> <Slot>\<该 Path 的内容>(Path 是文件时就是名为 <Slot> 的文件)
手写路径 -> <路径末级名>\...(历史布局,不变)
#>
# ----------------------------------------------------------------------------
# 加载器:下面这份点源顺序是**唯一**一份顺序声明。
#
# 每个函数一个文件,文件名 = 函数名;要合回单个 .psm1(发布形态,或做代码签名时需要),
# 跑 tools\Build-BakNRetModule.ps1 —— 它从本文件里读出顺序,所以顺序不需要维护两遍。
# ----------------------------------------------------------------------------
. (Join-Path $PSScriptRoot 'Private\State.ps1')
# ---- 日志 ----
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetDebug.ps1')
. (Join-Path $PSScriptRoot 'Public\Start-BakNRetLog.ps1')
. (Join-Path $PSScriptRoot 'Public\Stop-BakNRetLog.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetLogPath.ps1')
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetLog.ps1')
# ---- 运行锁 ----
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetRunLockPath.ps1')
. (Join-Path $PSScriptRoot 'Public\Enter-BakNRetRunLock.ps1')
. (Join-Path $PSScriptRoot 'Public\Exit-BakNRetRunLock.ps1')
# ---- 环境 ----
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetAdministrator.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetFreeSpaceGB.ps1')
# ---- 外部命令 ----
. (Join-Path $PSScriptRoot 'Public\ConvertTo-BakNRetNativeArgumentString.ps1')
. (Join-Path $PSScriptRoot 'Public\Invoke-ExternalCommand.ps1')
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetCompressionTool.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-Optimized7zArgument.ps1')
# ---- BackupList.txt 解析 ----
. (Join-Path $PSScriptRoot 'Public\Split-BakNRetToken.ps1')
. (Join-Path $PSScriptRoot 'Public\Remove-BakNRetQuote.ps1')
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetMarker.ps1')
. (Join-Path $PSScriptRoot 'Public\ConvertFrom-BakNRetPatternList.ps1')
. (Join-Path $PSScriptRoot 'Public\ConvertFrom-BackupListLine.ps1')
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetLiteralPath.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetRegexExclude.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetExcludeArgument.ps1')
. (Join-Path $PSScriptRoot 'Public\Split-BakNRetPatternScope.ps1')
. (Join-Path $PSScriptRoot 'Public\Merge-BakNRetExcludeArgument.ps1')
# ---- 软件名录(SoftwareCatalog.psd1) ----
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetCatalogPath.ps1')
. (Join-Path $PSScriptRoot 'Public\Format-BakNRetCatalogName.ps1')
. (Join-Path $PSScriptRoot 'Private\Test-BakNRetMapKey.ps1')
. (Join-Path $PSScriptRoot 'Private\Get-BakNRetMapValue.ps1')
. (Join-Path $PSScriptRoot 'Private\Get-BakNRetMapKeys.ps1')
. (Join-Path $PSScriptRoot 'Public\Expand-CatalogPathText.ps1')
. (Join-Path $PSScriptRoot 'Private\Import-BakNRetDataFile.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSoftwareCatalog.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetArchiveTopLevelNames.ps1')
. (Join-Path $PSScriptRoot 'Public\Find-BakNRetChildDirectoryByName.ps1')
# ---- 归档命名与路径还原 ----
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetItemArchiveName.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetArchiveTopName.ps1')
. (Join-Path $PSScriptRoot 'Public\New-BakNRetArchiveItem.ps1')
. (Join-Path $PSScriptRoot 'Public\New-BakNRetJunction.ps1')
. (Join-Path $PSScriptRoot 'Public\Remove-BakNRetJunction.ps1')
. (Join-Path $PSScriptRoot 'Public\New-BakNRetArchiveStaging.ps1')
. (Join-Path $PSScriptRoot 'Public\Remove-BakNRetArchiveStaging.ps1')
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetBackupEntry.ps1')
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetBackupEntryPlan.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetBackupBaseName.ps1')
. (Join-Path $PSScriptRoot 'Public\Convert-BakNRetBackupFileNameToPath.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetFolderSummary.ps1')
# ---- manifest.json ----
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetManifest.ps1')
. (Join-Path $PSScriptRoot 'Public\Sync-BakNRetManifestArchive.ps1')
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetManifest.ps1')
# ---- 归档原子替换 ----
. (Join-Path $PSScriptRoot 'Public\Move-BakNRetArchiveIntoPlace.ps1')
# ---- 安全描述符(NTFS 属主 / ACL) ----
. (Join-Path $PSScriptRoot 'Public\Enable-BakNRetPrivilege.ps1')
. (Join-Path $PSScriptRoot 'Public\ConvertTo-BakNRetWildcardPattern.ps1')
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetPathExcluded.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetAceSignatureList.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSecuritySddlWithStale.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSecurityRecord.ps1')
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetSecurityRecordNeeded.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetSecurityRecords.ps1')
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetAtomicText.ps1')
. (Join-Path $PSScriptRoot 'Public\Save-BakNRetSecuritySidecar.ps1')
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetSecuritySidecar.ps1')
. (Join-Path $PSScriptRoot 'Public\Convert-BakNRetSidMap.ps1')
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetObjectSecurity.ps1')
. (Join-Path $PSScriptRoot 'Public\Restore-BakNRetSecurity.ps1')
# ---- 配置 ----
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetConfig.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetPassword.ps1')
. (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetRootedPath.ps1')
. (Join-Path $PSScriptRoot 'Public\Test-BakNRetItemSelected.ps1')
. (Join-Path $PSScriptRoot 'Public\Find-BakNRet7zExecutable.ps1')
. (Join-Path $PSScriptRoot 'Public\New-BakNRetItemRecord.ps1')
. (Join-Path $PSScriptRoot 'Public\Save-BakNRetItemRecord.ps1')
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetRunSummary.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetCellWidth.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetKeyName.ps1')
. (Join-Path $PSScriptRoot 'Public\New-BakNRetInputDriver.ps1')
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetKey.ps1')
. (Join-Path $PSScriptRoot 'Public\Format-BakNRetPaddedText.ps1')
. (Join-Path $PSScriptRoot 'Public\Write-BakNRetAt.ps1')
. (Join-Path $PSScriptRoot 'Public\Update-BakNRetMenuState.ps1')
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetMenu.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetBackupListRow.ps1')
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetBackupListRow.ps1')
. (Join-Path $PSScriptRoot 'Public\Save-BakNRetConfigFile.ps1')
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetBackupListDirection.ps1')
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetBackupListEditor.ps1')
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetEntryScript.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetConfigSetting.ps1')
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetConfigSetting.ps1')
. (Join-Path $PSScriptRoot 'Public\Read-BakNRetLine.ps1')
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetConfigEditor.ps1')
. (Join-Path $PSScriptRoot 'Public\Get-BakNRetCatalogField.ps1')
. (Join-Path $PSScriptRoot 'Public\Set-BakNRetCatalogField.ps1')
. (Join-Path $PSScriptRoot 'Public\Invoke-BakNRetCatalogEditor.ps1')
Export-ModuleMember -Function @(
'Invoke-BakNRetCatalogEditor',
'Get-BakNRetCatalogField',
'Set-BakNRetCatalogField',
'Invoke-BakNRetConfigEditor',
'Read-BakNRetLine',
'Get-BakNRetConfigSetting',
'Set-BakNRetConfigSetting',
'Invoke-BakNRetEntryScript',
'Invoke-BakNRetBackupListEditor',
'Set-BakNRetBackupListDirection',
'Save-BakNRetConfigFile',
'Get-BakNRetBackupListRow',
'Set-BakNRetBackupListRow',
'Invoke-BakNRetMenu',
'Update-BakNRetMenuState',
'Format-BakNRetPaddedText',
'Write-BakNRetAt',
'Get-BakNRetKeyName',
'New-BakNRetInputDriver',
'Read-BakNRetKey',
'Get-BakNRetCellWidth',
'Write-BakNRetRunSummary',
'Save-BakNRetItemRecord',
'New-BakNRetItemRecord',
'Find-BakNRet7zExecutable',
'Resolve-BakNRetRootedPath',
'Test-BakNRetItemSelected',
'Enter-BakNRetRunLock',
'Exit-BakNRetRunLock',
'Get-BakNRetRunLockPath',
'Set-BakNRetDebug',
'Start-BakNRetLog',
'Stop-BakNRetLog',
'Get-BakNRetLogPath',
'Write-BakNRetLog',
'Test-BakNRetAdministrator',
'Get-BakNRetFreeSpaceGB',
'ConvertTo-BakNRetNativeArgumentString',
'Invoke-ExternalCommand',
'Resolve-BakNRetCompressionTool',
'Get-Optimized7zArgument',
'Split-BakNRetToken',
'Remove-BakNRetQuote',
'Test-BakNRetMarker',
'ConvertFrom-BakNRetPatternList',
'ConvertFrom-BackupListLine',
'Test-BakNRetLiteralPath',
'Get-BakNRetRegexExclude',
'Get-BakNRetExcludeArgument',
'Split-BakNRetPatternScope',
'Merge-BakNRetExcludeArgument',
'Resolve-BakNRetCatalogPath',
'Get-BakNRetSoftwareCatalog',
'Find-BakNRetChildDirectoryByName',
'Format-BakNRetCatalogName',
'Expand-CatalogPathText',
'Get-BakNRetArchiveTopLevelNames',
'Get-BakNRetArchiveTopName',
'New-BakNRetArchiveItem',
'New-BakNRetJunction',
'Remove-BakNRetJunction',
'New-BakNRetArchiveStaging',
'Remove-BakNRetArchiveStaging',
'Get-BakNRetItemArchiveName',
'Resolve-BakNRetBackupEntry',
'Write-BakNRetBackupEntryPlan',
'Get-BakNRetBackupBaseName',
'Convert-BakNRetBackupFileNameToPath',
'Get-BakNRetFolderSummary',
'Read-BakNRetManifest',
'Write-BakNRetManifest',
'Sync-BakNRetManifestArchive',
'Move-BakNRetArchiveIntoPlace',
'Enable-BakNRetPrivilege',
'ConvertTo-BakNRetWildcardPattern',
'Test-BakNRetPathExcluded',
'Get-BakNRetAceSignatureList',
'Get-BakNRetSecuritySddlWithStale',
'Get-BakNRetSecurityRecord',
'Test-BakNRetSecurityRecordNeeded',
'Get-BakNRetSecurityRecords',
'Write-BakNRetAtomicText',
'Save-BakNRetSecuritySidecar',
'Read-BakNRetSecuritySidecar',
'Convert-BakNRetSidMap',
'Set-BakNRetObjectSecurity',
'Restore-BakNRetSecurity',
'Get-BakNRetConfig',
'Get-BakNRetPassword'
)