Files
kefu/wechat_rpa/tmp/install-self-reply-fix.ps1
T
2026-09-21 10:34:06 +08:00

55 lines
4.5 KiB
PowerShell

$ErrorActionPreference = 'Stop'
$taskRoot = 'C:\kefu\wechat_rpa'
$taskRecordPath = Join-Path $taskRoot 'dist\installer\v1.4.9-verification.json'
$taskRecord = Get-Content -LiteralPath $taskRecordPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($taskRecord.status -ne 'verified') { throw 'Installer has not passed final verification' }
$taskInstaller = [string]$taskRecord.installer.path
if ((Get-FileHash -LiteralPath $taskInstaller -Algorithm SHA256).Hash -ne $taskRecord.installer.sha256) { throw 'Installer hash mismatch' }
$taskTarget = 'C:\Users\isard\AppData\Local\Programs\ZhenAIService'
$taskResolved = (Resolve-Path -LiteralPath $taskTarget).Path
if (-not [string]::Equals($taskResolved, $taskTarget, [StringComparison]::OrdinalIgnoreCase)) { throw 'Unexpected install target' }
$taskInternal = [IO.Path]::GetFullPath((Join-Path $taskResolved '_internal'))
if (-not $taskInternal.StartsWith($taskResolved + '\', [StringComparison]::OrdinalIgnoreCase)) { throw 'Runtime directory escaped install target' }
foreach ($taskPath in @($taskResolved, $taskInternal)) {
if ((Get-Item -LiteralPath $taskPath).Attributes -band [IO.FileAttributes]::ReparsePoint) { throw 'Install target contains a directory link' }
}
$taskLinks = @(Get-ChildItem -LiteralPath $taskInternal -Directory -Recurse -Force | Where-Object { $_.Attributes -band [IO.FileAttributes]::ReparsePoint })
if ($taskLinks.Count) { throw 'Runtime directory contains links; refusing recursive replacement' }
$taskProcesses = Get-CimInstance Win32_Process -Filter "Name LIKE 'ZhenAI-WeCom-Assistant-v%.exe'"
foreach ($taskProcess in $taskProcesses) {
if ($taskProcess.ExecutablePath -and [string]::Equals([IO.Path]::GetDirectoryName($taskProcess.ExecutablePath), $taskResolved, [StringComparison]::OrdinalIgnoreCase)) {
Stop-Process -Id $taskProcess.ProcessId -ErrorAction Stop
$taskExiting = Get-Process -Id $taskProcess.ProcessId -ErrorAction SilentlyContinue
if ($taskExiting -and -not $taskExiting.WaitForExit(10000)) { throw 'Old assistant did not exit' }
}
}
$taskData = 'C:\Users\isard\AppData\Local\ZhenYangTangRPA'
$taskDataHashes = @{}
foreach ($taskName in @('conversations.json','pending_replies.json','app_settings.json','ai_settings.json','wxwork_keys.json')) {
$taskFile = Join-Path $taskData $taskName
if (Test-Path -LiteralPath $taskFile -PathType Leaf) { $taskDataHashes[$taskName] = (Get-FileHash -LiteralPath $taskFile -Algorithm SHA256).Hash }
}
Write-Output 'Installing verified v1.4.9 into the existing assistant program directory.'
$taskInstall = Start-Process -FilePath $taskInstaller -ArgumentList ('/S /D=' + $taskResolved) -WindowStyle Hidden -PassThru
$taskInstall.WaitForExit()
if ($taskInstall.ExitCode -ne 0) { throw ('Installer failed: ' + $taskInstall.ExitCode) }
$taskExe = Join-Path $taskResolved 'ZhenAI-WeCom-Assistant-v1.4.9.exe'
$taskExeHash = (Get-FileHash -LiteralPath $taskExe -Algorithm SHA256).Hash
if ($taskExeHash -ne $taskRecord.app.sha256) { throw 'Installed EXE hash mismatch' }
Write-Output 'Installed EXE matches the validated build; running local self-check.'
$taskOldPath = $env:PATH
try {
$env:PATH = (Join-Path $env:SystemRoot 'System32') + ';' + $env:SystemRoot
$taskCheck = Start-Process -FilePath $taskExe -ArgumentList '--packaging-self-check' -WorkingDirectory $taskResolved -WindowStyle Hidden -PassThru
} finally { $env:PATH = $taskOldPath }
if (-not $taskCheck.WaitForExit(90000)) { $taskCheck.Kill(); throw 'Installed self-check timed out' }
if ($taskCheck.ExitCode -ne 0) { throw ('Installed self-check failed: ' + $taskCheck.ExitCode) }
foreach ($taskName in $taskDataHashes.Keys) {
if ((Get-FileHash -LiteralPath (Join-Path $taskData $taskName) -Algorithm SHA256).Hash -ne $taskDataHashes[$taskName]) { throw ('User data changed during install: ' + $taskName) }
}
$taskVersion = (Get-ItemProperty -LiteralPath 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Uninstall\ZhenAIService').DisplayVersion
if ($taskVersion -ne '1.4.9') { throw 'Installed version registration mismatch' }
$taskResult = [ordered]@{version='1.4.9';path=$taskExe;sha256=$taskExeHash;installer_exit_code=$taskInstall.ExitCode;self_check_exit_code=$taskCheck.ExitCode;user_data_preserved=$true;user_data_files=@($taskDataHashes.Keys);listener_started=$false}
$taskResult | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath (Join-Path $taskRoot 'tmp\self-reply-local-install-verification.json') -Encoding UTF8
Write-Output 'Local installation verified; chat records and settings preserved; listener remains stopped.'