param( [Parameter(Mandatory=$true)][string]$Executable, [Parameter(Mandatory=$true)][string]$OutputDirectory, [ValidateSet('文件传输助手','消息测试专用群组')][string]$Session='消息测试专用群组', [switch]$IncludeMentions ) if($IncludeMentions -and $Session -ne '消息测试专用群组'){throw 'Mention validation is restricted to the approved test group.'} $ErrorActionPreference='Stop' $exe=(Resolve-Path $Executable).Path if(Test-Path $OutputDirectory){throw 'Use a fresh evidence directory.'} $directory=(New-Item -ItemType Directory $OutputDirectory).FullName $checks=New-Object System.Collections.Generic.List[object] $marker='wx-agent-general-'+[Guid]::NewGuid().ToString('N') function Invoke-Check([string]$Stage,[string[]]$Arguments){ # Record the attempt before execution. Never retry a send, including an unconfirmed result. @{Stage=$Stage;StartedUtc=[DateTime]::UtcNow.ToString('o')} | ConvertTo-Json | Set-Content "$directory\$Stage-attempt.json" -Encoding UTF8 $raw=(& $exe @Arguments 2> "$directory\$Stage.stderr.txt" | Out-String) $code=$LASTEXITCODE $raw | Set-Content "$directory\$Stage.json" -Encoding UTF8 $checks.Add(@{Stage=$Stage;ExitCode=$code}) if($code -ne 0){throw "$Stage failed; no further operations will run."} } try { Invoke-Check 'doctor' @('doctor','--timeout','30') Invoke-Check 'inspect-ui' @('inspect-ui','--output',"$directory\ui-tree.json",'--timeout','30') Invoke-Check 'smoke' @('smoke','--timeout','60') $file=Join-Path $directory "$marker.txt" [IO.File]::WriteAllText($file,$marker) Add-Type -AssemblyName System.Drawing $image=Join-Path $directory "$marker.png" $bitmap=New-Object Drawing.Bitmap 32,32 try { $bitmap.SetPixel(16,16,[Drawing.Color]::Blue); $bitmap.Save($image,[Drawing.Imaging.ImageFormat]::Png) } finally { $bitmap.Dispose() } Invoke-Check 'send-multiline' @('chat','send','--session',$Session,'--text',"$marker-line1`r`n`r`n$marker-line3",'--timeout','60') Invoke-Check 'send-file' @('chat','send-file','--session',$Session,'--path',$file,'--timeout','60') Invoke-Check 'send-image' @('chat','send-image','--session',$Session,'--path',$image,'--timeout','60') Invoke-Check 'reply-latest' @('chat','reply-latest','--session',$Session,'--text',"$marker-reply1`r`n`r`n$marker-reply3",'--timeout','60') if($IncludeMentions){ Invoke-Check 'mention-member' @('chat','mention','--session',$Session,'--member','Hao 豪','--text',"$marker-member",'--confirm','CONFIRM','--timeout','60') Invoke-Check 'mention-all' @('chat','mention','--session',$Session,'--member','所有人','--text',"$marker-all",'--confirm','CONFIRM','--timeout','60') } } catch { @{Message=$_.Exception.Message;Line=$_.InvocationInfo.ScriptLineNumber} | ConvertTo-Json | Set-Content "$directory\error.json" -Encoding UTF8 } finally { $expectedCount=7 if($IncludeMentions){$expectedCount=9} $success=($checks.Count -eq $expectedCount -and @($checks | Where-Object {$_.ExitCode -ne 0}).Count -eq 0) @{Success=$success;Checks=@($checks.ToArray());MentionAttempted=(@($checks | Where-Object {$_.Stage -eq 'mention-member'}).Count -gt 0);BinarySha256=(Get-FileHash $exe -Algorithm SHA256).Hash} | ConvertTo-Json -Depth 6 | Set-Content "$directory\summary.json" -Encoding UTF8 } if(!$success){exit 1}