Files
clipbin-desktop/scripts/validate/windows.ps1
T
harry 3588d5b212 docs: add validation guide, hardware and Windows scripts, CI
Documents what the rig proved and what it found, adds the hardware sign-off
script for the Hyprland machine and an (untested) Windows validation script,
and updates CI to build the cached OBS runtime, run tests and lint the Windows
code paths.
2026-10-08 14:31:54 +02:00

81 lines
4.0 KiB
PowerShell

# Hardware validation for Windows. Not yet run on Windows: it is the first
# job for the Windows implementor, who should fix what it finds.
#
# powershell -ExecutionPolicy Bypass -File scripts\validate\windows.ps1 [-Out <dir>] [-GameWindow "<title>:<class>:<exe>"]
#
# Needs: Rust (rustup, MSVC toolchain), Visual Studio Build Tools (C++),
# Git for Windows (its bash runs scripts/obs/assemble-windows.sh) and FFmpeg
# on PATH for the segment checks (winget install Gyan.FFmpeg).
#
# -GameWindow is OBS's window identifier for a running game, as shown in OBS
# Studio's Game Capture "Window" list: "<title>:<window class>:<executable>".
param(
[string]$Out = "$env:TEMP\clipbin-windows",
[string]$GameWindow = ""
)
$ErrorActionPreference = "Stop"
$repo = Resolve-Path "$PSScriptRoot\..\.."
$report = Join-Path $Out "report.txt"
Remove-Item -Recurse -Force $Out -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force $Out | Out-Null
function Log($text) { $text | Tee-Object -FilePath $report -Append }
Log "Clipbin Windows validation $(Get-Date -Format o)"
Log "os: $((Get-CimInstance Win32_OperatingSystem).Caption) $([Environment]::OSVersion.Version)"
Log "gpu: $((Get-CimInstance Win32_VideoController).Name -join ', ')"
# 1. The pinned official OBS runtime, with the Game Capture hook still signed.
& bash "$repo/scripts/obs/assemble-windows.sh"
if ($LASTEXITCODE -ne 0) { throw "assembling the OBS runtime failed" }
$runtime = Join-Path $repo "target\obs-runtime\windows-x86_64"
Get-ChildItem "$runtime\data\obs-plugins\win-capture\*" -Include *.exe, *.dll | ForEach-Object {
$signature = Get-AuthenticodeSignature $_.FullName
Log ("signature {0}: {1} ({2})" -f $_.Name, $signature.Status, $signature.SignerCertificate.Subject)
}
# 2. Build the probe (also checks the Windows code paths compile and link).
Push-Location $repo
cargo build --locked -p clipbin-probe
if ($LASTEXITCODE -ne 0) { throw "building clipbin-probe failed" }
Pop-Location
$probe = Join-Path $repo "target\debug\clipbin-probe.exe"
$format = @("--width", "2560", "--height", "1440", "--fps", "60", "--bitrate", "40000")
function Record($name, $codec, [string[]]$arguments) {
$dir = Join-Path $Out $name
& $probe record @arguments --codec $codec @format --seconds 20 --out $dir > "$dir.log" 2> "$dir.obs.log"
$recordExit = $LASTEXITCODE
& $probe check --codec $codec --out $dir >> "$dir.log" 2>&1
$checkExit = $LASTEXITCODE
Log "${name}: record_exit=$recordExit check_exit=$checkExit $((Select-String -Path "$dir.log" -Pattern '^(encoder|recorded|check)=').Line -join ' ')"
Log ((Select-String -Path "$dir.log" -Pattern 'status=').Line -join ' ')
}
# 3. Hardware encoders: NVENC, AMF or QSV for H.264, HEVC and AV1.
& $probe encoders --verify @format --out (Join-Path $Out "encoders") > "$Out\encoders.log" 2> "$Out\encoders.obs.log"
Log ((Select-String -Path "$Out\encoders.log" -Pattern '^(obs_version|usable\.|verify\.)').Line -join "`n")
# 4. Monitor capture with each usable codec.
foreach ($codec in "h264", "hevc", "av1") {
if (Select-String -Path "$Out\encoders.log" -Pattern "^usable\.$codec=none" -Quiet) {
Log "SKIP ${codec}: no usable hardware encoder"
continue
}
Record "monitor-$codec" $codec @("--target", "monitor")
}
# 5. Game Capture (signed hook) and Window Capture of a running game.
if ($GameWindow) {
Record "game-capture" "h264" @("--target", "game", "--window", $GameWindow)
Record "window-capture" "h264" @("--target", "window", "--window", $GameWindow)
Write-Host "Last: start a recording, then quit the game about 5 seconds in."
Read-Host "Press Enter when ready"
$dir = Join-Path $Out "game-closed"
& $probe record --target game --window $GameWindow @format --seconds 20 --out $dir > "$dir.log" 2> "$dir.obs.log"
Log "game-closed: exit=$LASTEXITCODE $((Select-String -Path "$dir.log" -Pattern 'status=failed').Line | Select-Object -First 1)"
} else {
Log "SKIP game capture: pass -GameWindow with a running game's window identifier"
}
Write-Host "Report: $report"