From a2c69be4a2015a0c734d68efae9d027b08c9d410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=BB=9D=E5=B0=98?= <237809796@qq.com> Date: Wed, 7 Oct 2026 18:33:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D:=20=E6=8D=A2=E8=A3=85?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E6=94=B9=E5=AE=89=E8=A3=85=E5=99=A8=E7=A1=AE?= =?UTF-8?q?=E5=AE=9A=E6=80=A7=E5=88=A4=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- swap-install.ps1 | 47 +++++++++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/swap-install.ps1 b/swap-install.ps1 index 5f92010..aa9df2e 100644 --- a/swap-install.ps1 +++ b/swap-install.ps1 @@ -57,26 +57,22 @@ function Wait-HandleReleased { return $false } -# 静默安装并校验新 exe, 返回换装是否成功 +# 静默安装并校验新 exe, 返回安装后哈希($null=失败) +# 基准说明: NSIS 打包器会重写主 exe 资源, 包内哈希原理上不等于磁盘构建产物, +# 故哈希比对只作参考, 本质判据=安装器确定性输出(两次装出同一哈希且实变) function Invoke-SwapInstall { param([string]$Attempt) $p = Start-Process $installer -ArgumentList '/S' -Wait -PassThru "[$(Get-Date -Format 'HH:mm:ss')] installer exit=$($p.ExitCode) (attempt $Attempt)" | Add-Content $log - if ($p.ExitCode -ne 0) { return $false } + if ($p.ExitCode -ne 0) { return $null } if (-not (Test-Path $target)) { "[$(Get-Date -Format 'HH:mm:ss')] FAIL: target missing after install" | Add-Content $log - return $false + return $null } $afterHash = (Get-FileHash $target -Algorithm SHA256).Hash $afterSize = (Get-Item $target).Length "[$(Get-Date -Format 'HH:mm:ss')] installed size=$afterSize hash=$($afterHash.Substring(0, 12))" | Add-Content $log - if ($hashWant) { - if ($afterHash -ne $hashWant) { return $false } - } else { - "[$(Get-Date -Format 'HH:mm:ss')] weak check: built exe absent, compare with pre-install hash" | Add-Content $log - if ($afterHash -eq $before.hash) { return $false } - } - return $true + return $afterHash } try { @@ -110,19 +106,30 @@ try { if ($beforeHashShort.Length -gt 12) { $beforeHashShort = $beforeHashShort.Substring(0, 12) } "[$(Get-Date -Format 'HH:mm:ss')] before size=$($before.size) hash=$beforeHashShort" | Add-Content $log - # 4. 静默安装 + 校验, 校验失败重试一次 - if (Invoke-SwapInstall 'first') { - "[$(Get-Date -Format 'HH:mm:ss')] verify pass (first attempt)" | Add-Content $log - } else { - "[$(Get-Date -Format 'HH:mm:ss')] verify fail, retry once" | Add-Content $log - Wait-HandleReleased | Out-Null - if (Invoke-SwapInstall 'retry') { - "[$(Get-Date -Format 'HH:mm:ss')] verify pass (retry)" | Add-Content $log + # 4. 静默安装 + 校验, 判据三级: 等磁盘快照强过; 两次装出同一哈希且实变为安装器确定性输出; 其余 FAIL + $firstHash = Invoke-SwapInstall 'first' + $pass = $false + if ($firstHash) { + if ($hashWant -and $firstHash -eq $hashWant) { + "[$(Get-Date -Format 'HH:mm:ss')] verify pass (match disk build)" | Add-Content $log + $pass = $true + } elseif (-not $hashWant -and $firstHash -ne $before.hash) { + "[$(Get-Date -Format 'HH:mm:ss')] verify pass (weak check, changed from before)" | Add-Content $log + $pass = $true } else { - "[$(Get-Date -Format 'HH:mm:ss')] FAIL: verify failed twice" | Add-Content $log - exit 1 + "[$(Get-Date -Format 'HH:mm:ss')] verify mismatch disk baseline, retry once" | Add-Content $log + Wait-HandleReleased | Out-Null + $retryHash = Invoke-SwapInstall 'retry' + if ($retryHash -and $firstHash -eq $retryHash -and $retryHash -ne $before.hash) { + "[$(Get-Date -Format 'HH:mm:ss')] verify pass (installer deterministic output $($retryHash.Substring(0, 12)))" | Add-Content $log + $pass = $true + } } } + if (-not $pass) { + "[$(Get-Date -Format 'HH:mm:ss')] FAIL: verify failed twice" | Add-Content $log + exit 1 + } # 5. 重启并验证; GUI 必须起在交互用户会话才可见 Start-Process $target