<# .SYNOPSIS BakNRet 主入口:不带参数时进 TUI 菜单;带 -Action 时按动作执行。 .DESCRIPTION 不带参数 = 交互式界面(TUI 主菜单)。带 `-Action Backup|Restore|Config` = 直接做那个动作, 可以配 `-Quiet` 走无头。 为什么动作仍然是**子进程**(而不是把编排搬进模块):一份编排、两个前端是终局目标(ADR-0012), 但那要求先把编排从入口脚本里下沉进模块 —— 那是另一大块工作。先让 TUI 能用起来,等下沉做完 再把这里的子进程调用换成进程内直调,界面层不受影响。 -Quiet:调用方要拿输出(管道 / 日志 / 计划任务),所以捕获并转发子进程的输出。 不加 -Quiet 时子进程继承控制台:输出实时、顺序正确、还能接键盘。 退出码:动作的退出码**原样传出**(计划任务靠它)。只有两种情况由本脚本自己给码: 既没有控制台又没有 -InputScript(无法进交互界面)→ 2;在菜单里按 Esc 退出 → 0。 绝不挂起:进不了界面就明确失败(ADR-0010)。 .EXAMPLE .\Manage-Backup.ps1 # 进 TUI 菜单 .EXAMPLE .\Manage-Backup.ps1 -Action Backup -Quiet -DryRun #> [CmdletBinding()] param( [ValidateSet('Backup', 'Restore', 'Config')][string]$Action, [switch]$Quiet, [string[]]$InputScript, [Parameter(ValueFromRemainingArguments = $true)]$Rest ) $ErrorActionPreference = 'Stop' $savedVerbosePreference = $VerbosePreference $VerbosePreference = 'SilentlyContinue' Import-Module (Join-Path $PSScriptRoot 'BakNRet\BakNRet.psd1') -Force $VerbosePreference = $savedVerbosePreference # -Verbose / -Debug 是通用参数,**不会**落进 $Rest,所以要显式转发(垫片那一轮踩过这个坑) $forwardExtra = @($Rest) + @(if ($PSBoundParameters.ContainsKey('Verbose')) { '-Verbose' }) + @(if ($PSBoundParameters.ContainsKey('Debug')) { '-Debug' }) $entryFor = @{ 'Backup' = 'Backup-Data.ps1' 'Restore' = 'Restore-Data.ps1' 'Config' = 'Edit-Config.ps1' } if ($Action) { $target = Join-Path $PSScriptRoot $entryFor[$Action] if ($Quiet) { $exitCode = Invoke-BakNRetEntryScript -Path $target -ArgumentList $forwardExtra -Capture } else { $exitCode = Invoke-BakNRetEntryScript -Path $target -ArgumentList $forwardExtra } exit $exitCode } # 不带 -Action:进 TUI 主菜单。进不去就明确失败,绝不挂起。 if ([Console]::IsOutputRedirected -and -not $InputScript) { Write-Host '没有可用的控制台,也没有给出 -InputScript:无法进入交互界面。' -ForegroundColor Red Write-Host '要非交互执行,请指定动作,例如:-Action Backup -Quiet' -ForegroundColor Red exit 2 } $driver = New-BakNRetInputDriver -Script $InputScript -NonInteractive:$([bool]$InputScript) $items = @( [pscustomobject]@{ Key = 'Backup'; Text = '备份  把清单里该备份的条目打包' } [pscustomobject]@{ Key = 'Restore'; Text = '恢复  从归档恢复(含干跑与校验)' } [pscustomobject]@{ Key = 'Config'; Text = '配置  清单 / 设置 / 名录' } ) $picked = Invoke-BakNRetMenu -Title 'BakNRet' -Items $items -Driver $driver -MultiSelect $false -Hint '↑↓ 选择 回车 进入 Esc 退出' if ($picked.Action -ne 'confirm') { exit 0 } $target = Join-Path $PSScriptRoot $entryFor[$picked.Chosen.Key] exit (Invoke-BakNRetEntryScript -Path $target -ArgumentList $forwardExtra)