| New file |
| | |
| | | param( |
| | | [switch]$CollectOnly, |
| | | [switch]$NoLaunch, |
| | | [int]$WaitSeconds = 45 |
| | | ) |
| | | |
| | | $ErrorActionPreference = "Stop" |
| | | |
| | | function Write-Step { |
| | | param([string]$Message) |
| | | Write-Host "" |
| | | Write-Host "== $Message ==" -ForegroundColor Cyan |
| | | } |
| | | |
| | | function Add-Result { |
| | | param( |
| | | [System.Collections.Generic.List[string]]$Results, |
| | | [string]$Name, |
| | | [bool]$Passed, |
| | | [string]$Detail = "" |
| | | ) |
| | | $state = if ($Passed) { "PASS" } else { "NEEDS_EVIDENCE" } |
| | | $line = if ($Detail) { "$state`t$Name`t$Detail" } else { "$state`t$Name" } |
| | | $Results.Add($line) | Out-Null |
| | | $color = if ($Passed) { "Green" } else { "Yellow" } |
| | | Write-Host "[$state] $Name $Detail" -ForegroundColor $color |
| | | } |
| | | |
| | | $PackageDir = Split-Path -Parent $MyInvocation.MyCommand.Path |
| | | $ExePath = Join-Path $PackageDir "PrivateVoice Dictation.exe" |
| | | $RequiredFiles = @( |
| | | "PrivateVoice Dictation.exe", |
| | | "onnxruntime.dll", |
| | | "sherpa-onnx-c-api.dll", |
| | | "sherpa-onnx-cxx-api.dll" |
| | | ) |
| | | $AppDataDir = Join-Path $env:APPDATA "PrivateVoice Input" |
| | | $LogPath = Join-Path $AppDataDir "app.log" |
| | | $Timestamp = Get-Date -Format "yyyyMMdd-HHmmss" |
| | | $EvidenceDir = Join-Path $PackageDir "qa-evidence-$Timestamp" |
| | | $Results = [System.Collections.Generic.List[string]]::new() |
| | | |
| | | New-Item -ItemType Directory -Path $EvidenceDir -Force | Out-Null |
| | | |
| | | Write-Step "PrivateVoice Windows preview QA" |
| | | "GeneratedAt: $(Get-Date -Format o)" | Set-Content -Encoding UTF8 (Join-Path $EvidenceDir "qa-summary.txt") |
| | | "PackageDir: $PackageDir" | Add-Content -Encoding UTF8 (Join-Path $EvidenceDir "qa-summary.txt") |
| | | "AppDataDir: $AppDataDir" | Add-Content -Encoding UTF8 (Join-Path $EvidenceDir "qa-summary.txt") |
| | | |
| | | Write-Step "Checking package files" |
| | | foreach ($file in $RequiredFiles) { |
| | | $path = Join-Path $PackageDir $file |
| | | Add-Result $Results "file exists: $file" (Test-Path $path) $path |
| | | } |
| | | |
| | | Write-Step "Collecting system information" |
| | | try { |
| | | Get-ComputerInfo | Select-Object WindowsProductName, WindowsVersion, OsHardwareAbstractionLayer, CsSystemType, CsProcessors, CsTotalPhysicalMemory | |
| | | Format-List | Out-String | Set-Content -Encoding UTF8 (Join-Path $EvidenceDir "system-info.txt") |
| | | Add-Result $Results "system info collected" $true |
| | | } catch { |
| | | Add-Result $Results "system info collected" $false $_.Exception.Message |
| | | } |
| | | |
| | | if (-not $CollectOnly -and -not $NoLaunch) { |
| | | Write-Step "Launching app" |
| | | if (-not (Test-Path $ExePath)) { |
| | | throw "Missing executable: $ExePath" |
| | | } |
| | | Start-Process -FilePath $ExePath -WorkingDirectory $PackageDir | Out-Null |
| | | } |
| | | |
| | | Write-Step "Waiting for app log" |
| | | $deadline = (Get-Date).AddSeconds($WaitSeconds) |
| | | while ((Get-Date) -lt $deadline -and -not (Test-Path $LogPath)) { |
| | | Start-Sleep -Milliseconds 500 |
| | | } |
| | | Add-Result $Results "app log exists" (Test-Path $LogPath) $LogPath |
| | | |
| | | Write-Step "Checking process" |
| | | $processes = Get-Process | Where-Object { $_.ProcessName -like "PrivateVoice*" -or $_.Path -eq $ExePath } | Select-Object Id, ProcessName, Path |
| | | $processes | Format-Table -AutoSize | Out-String | Set-Content -Encoding UTF8 (Join-Path $EvidenceDir "processes.txt") |
| | | Add-Result $Results "PrivateVoice process visible" (($processes | Measure-Object).Count -gt 0) |
| | | |
| | | if (-not $CollectOnly) { |
| | | Write-Step "Manual runtime check" |
| | | Write-Host "1. Keep this PowerShell window open." -ForegroundColor White |
| | | Write-Host "2. In PrivateVoice, make sure the SenseVoice model is installed and the engine is ready." -ForegroundColor White |
| | | Write-Host "3. Open Notepad or a browser text field." -ForegroundColor White |
| | | Write-Host "4. Use the configured hotkey and speak: 这是 Windows 预览版测试。" -ForegroundColor White |
| | | Write-Host "5. Confirm whether the text appears in the target input field." -ForegroundColor White |
| | | Read-Host "Press Enter after you complete one dictation attempt" |
| | | } |
| | | |
| | | Write-Step "Collecting logs" |
| | | if (Test-Path $LogPath) { |
| | | Copy-Item $LogPath (Join-Path $EvidenceDir "app.log") -Force |
| | | $logText = Get-Content $LogPath -Raw -ErrorAction SilentlyContinue |
| | | Add-Result $Results "startup log found" ($logText -match "PrivateVoice Dictation starting") |
| | | Add-Result $Results "engine ready log found" ($logText -match "ASR engine ready|Engine initialized") |
| | | Add-Result $Results "recording log found" ($logText -match "Recording started") |
| | | Add-Result $Results "recognized text log found" ($logText -match "Recognized:") |
| | | Add-Result $Results "paste success log found" ($logText -match "PERF paste_done.*result=success|PERF fallback_type_done.*result=success") |
| | | } |
| | | |
| | | $ConfigPath = Join-Path $AppDataDir "config.json" |
| | | if (Test-Path $ConfigPath) { |
| | | Copy-Item $ConfigPath (Join-Path $EvidenceDir "config.json") -Force |
| | | } |
| | | |
| | | $Results | Set-Content -Encoding UTF8 (Join-Path $EvidenceDir "qa-results.tsv") |
| | | $Results | Add-Content -Encoding UTF8 (Join-Path $EvidenceDir "qa-summary.txt") |
| | | |
| | | Write-Step "Evidence package" |
| | | $ZipPath = "$EvidenceDir.zip" |
| | | if (Test-Path $ZipPath) { |
| | | Remove-Item $ZipPath -Force |
| | | } |
| | | Compress-Archive -Path (Join-Path $EvidenceDir "*") -DestinationPath $ZipPath |
| | | Write-Host "Evidence directory: $EvidenceDir" -ForegroundColor Green |
| | | Write-Host "Evidence zip: $ZipPath" -ForegroundColor Green |
| | | |
| | | Write-Host "" |
| | | Write-Host "Send back the evidence zip if any check is NEEDS_EVIDENCE or the app does not behave correctly." -ForegroundColor Yellow |