From 67ee2af00625e893cc1e3dd893287c25dcec8d51 Mon Sep 17 00:00:00 2001 From: Shuery <2463253700@qq.com> Date: Sun, 27 Sep 2026 10:31:05 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E4=B8=A4=E4=B8=AA=E5=85=A5?= =?UTF-8?q?=E5=8F=A3=E7=BB=9F=E4=B8=80=207z=20=E7=9A=84=E6=9F=A5=E6=89=BE?= =?UTF-8?q?=E6=96=B9=E5=BC=8F=EF=BC=88=E6=B6=88=E9=99=A4=E2=80=9C=E5=A4=87?= =?UTF-8?q?=E4=BB=BD=E6=89=BE=E5=BE=97=E5=88=B0=E3=80=81=E6=81=A2=E5=A4=8D?= =?UTF-8?q?=E6=89=BE=E4=B8=8D=E5=88=B0=E2=80=9D=E7=9A=84=E9=9A=90=E6=82=A3?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 原先同一段查找逻辑有两份:模块的 Resolve-BakNRetCompressionTool 里一份,Restore.ps1 自带的 Get-7zExecutable 里又一份(PATH → Program Files → Program Files (x86))。两套写法哪怕只差一个候选路径,就会出现“备份找得到、恢复找不到”这种最难看的不一致。 抽成 Find-BakNRet7zExecutable,两边都改用它。**保持策略不同**:备份可以退到 RAR 或内置 ZIP(能打包就行),恢复必须真能解压 7z、找不到就明确报错 —— 所以抽出来的只负责“找 7z”,不负责“找不到怎么办”。我自己在抽之前差点把它当成顺手删的重复代码,看清楚才发现策略差异是刻意的。 验收:test.ps1 9/9 全绿(7 与 5.1)、103 个文件两版解析零错、真实清单只读冒烟 4/4、构建工具仍能合回单文件。当前查找器在本机解析到 C:\Programs\Scoop\shims\7z.exe,备份侧解析器仍返回 7z。 --- BakNRet/BakNRet.psd1 | 1 + BakNRet/BakNRet.psm1 | 3 +++ BakNRet/Public/Find-BakNRet7zExecutable.ps1 | 23 +++++++++++++++++++ .../Public/Resolve-BakNRetCompressionTool.ps1 | 10 +------- Restore.ps1 | 18 +++------------ 5 files changed, 31 insertions(+), 24 deletions(-) create mode 100644 BakNRet/Public/Find-BakNRet7zExecutable.ps1 diff --git a/BakNRet/BakNRet.psd1 b/BakNRet/BakNRet.psd1 index c846c11..d9e9ea1 100644 --- a/BakNRet/BakNRet.psd1 +++ b/BakNRet/BakNRet.psd1 @@ -19,6 +19,7 @@ CompatiblePSEditions = @('Desktop', 'Core') FunctionsToExport = @( + 'Find-BakNRet7zExecutable', 'Resolve-BakNRetRootedPath', 'Test-BakNRetItemSelected', 'Enter-BakNRetRunLock', diff --git a/BakNRet/BakNRet.psm1 b/BakNRet/BakNRet.psm1 index 93193f0..03668c3 100644 --- a/BakNRet/BakNRet.psm1 +++ b/BakNRet/BakNRet.psm1 @@ -136,7 +136,10 @@ . (Join-Path $PSScriptRoot 'Public\Resolve-BakNRetRootedPath.ps1') . (Join-Path $PSScriptRoot 'Public\Test-BakNRetItemSelected.ps1') +. (Join-Path $PSScriptRoot 'Public\Find-BakNRet7zExecutable.ps1') + Export-ModuleMember -Function @( + 'Find-BakNRet7zExecutable', 'Resolve-BakNRetRootedPath', 'Test-BakNRetItemSelected', 'Enter-BakNRetRunLock', diff --git a/BakNRet/Public/Find-BakNRet7zExecutable.ps1 b/BakNRet/Public/Find-BakNRet7zExecutable.ps1 new file mode 100644 index 0000000..ade45f7 --- /dev/null +++ b/BakNRet/Public/Find-BakNRet7zExecutable.ps1 @@ -0,0 +1,23 @@ +function Find-BakNRet7zExecutable { + <# + .SYNOPSIS + 定位 7z.exe:PATH 优先,其次是两个常见安装位置;找不到返回 $null。 + + .DESCRIPTION + 为什么要单独抽出来:这段查找逻辑原先有两份 —— 模块里的 Resolve-BakNRetCompressionTool + 有一份,Restore.ps1 里还有一个自带的 Get-7zExecutable。两套写法哪怕只差一个候选路径, + 就会出现"备份找得到、恢复找不到"这种最难看的不一致。 + + 注意这里只负责**找 7z**,不负责"找不到怎么办":那个策略两边本就不同 —— 备份可以退到 + RAR 或内置 ZIP(能打包就行),而恢复必须真的能解压 7z,找不到就该明确报错。 + #> + $sevenZip = Get-Command 7z -ErrorAction SilentlyContinue | + Select-Object -First 1 -ExpandProperty Source + if ($sevenZip) { return $sevenZip } + + $candidates = @( + (Join-Path $env:ProgramFiles '7-Zip\7z.exe'), + (Join-Path ${env:ProgramFiles(x86)} '7-Zip\7z.exe') + ) + return ($candidates | Where-Object { $_ -and (Test-Path -LiteralPath $_) } | Select-Object -First 1) +} diff --git a/BakNRet/Public/Resolve-BakNRetCompressionTool.ps1 b/BakNRet/Public/Resolve-BakNRetCompressionTool.ps1 index e80aaa4..bf0a189 100644 --- a/BakNRet/Public/Resolve-BakNRetCompressionTool.ps1 +++ b/BakNRet/Public/Resolve-BakNRetCompressionTool.ps1 @@ -7,15 +7,7 @@ 只返回工具身份,不再返回没人用的 FullArgs / FallbackArgs (旧实现里 7z 的那两份参数是死代码,真正的参数由 Get-Optimized7zArgument 生成)。 #> - $sevenZip = Get-Command 7z -ErrorAction SilentlyContinue | - Select-Object -First 1 -ExpandProperty Source - if (-not $sevenZip) { - $candidates = @( - (Join-Path $env:ProgramFiles '7-Zip\7z.exe'), - (Join-Path ${env:ProgramFiles(x86)} '7-Zip\7z.exe') - ) - $sevenZip = $candidates | Where-Object { $_ -and (Test-Path -LiteralPath $_) } | Select-Object -First 1 - } + $sevenZip = Find-BakNRet7zExecutable if ($sevenZip) { Write-BakNRetLog '检测到 7z 压缩工具' -Level DEBUG return [pscustomobject]@{ Name = '7z'; Command = $sevenZip; Extension = '.7z' } diff --git a/Restore.ps1 b/Restore.ps1 index 924e020..5d67ec3 100644 --- a/Restore.ps1 +++ b/Restore.ps1 @@ -163,18 +163,6 @@ function Get-ArchiveForEntry { return $null } -function Get-7zExecutable { - <# .SYNOPSIS 定位 7z.exe(PATH 优先,其次是常见安装位置)。 #> - $sevenZip = Get-Command 7z -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty Source - if (-not $sevenZip) { - $candidates = @( - (Join-Path $env:ProgramFiles '7-Zip\7z.exe'), - (Join-Path ${env:ProgramFiles(x86)} '7-Zip\7z.exe') - ) - $sevenZip = $candidates | Where-Object { $_ -and (Test-Path -LiteralPath $_) } | Select-Object -First 1 - } - return $sevenZip -} function Invoke-ExtractionRaw { <# @@ -197,7 +185,7 @@ function Invoke-ExtractionRaw { New-Item -ItemType Directory -Path $Destination -Force | Out-Null } - $sevenZip = Get-7zExecutable + $sevenZip = Find-BakNRet7zExecutable if ($sevenZip) { Write-BakNRetLog '使用 7z 解压' -Level DEBUG $argument = @('x', '-bsp2', '-y', "-o$Destination") @@ -371,7 +359,7 @@ function Test-BakNRetArchivePath { [string]$Password ) - $sevenZip = Get-7zExecutable + $sevenZip = Find-BakNRet7zExecutable if (-not $sevenZip) { return $true } # 没有 7z 时不预判,交给解压分支自己去失败 $item = ([string]$RelativePath).Trim([char[]]@('\', '/')) @@ -646,7 +634,7 @@ foreach ($line in $lines) { Write-BakNRetLog "跳过校验(非 7z): $($archiveFile.Name)" -Level DEBUG continue } - $verifyTool = Get-7zExecutable + $verifyTool = Find-BakNRet7zExecutable if (-not $verifyTool) { Write-BakNRetLog '未找到 7z,无法校验' -Level ERROR $stats.failed++