param( [string]$SunshineLogPath = "", [int]$MaxLogAgeMinutes = 30 ) # 只读验收脚本:不重启 VM、设备、VFIO 或 Sunshine,不修改任何配置。 # 退出码 0 才表示当前状态满足“可继续做串流性能验收”的前置条件。 $ErrorActionPreference = "Stop" $ok = $true function Report([string]$Name, [bool]$Passed, [string]$Detail) { $state = if ($Passed) { "PASS" } else { "FAIL" } Write-Output ("[{0}] {1}: {2}" -f $state, $Name, $Detail) } $nvidiaCommand = Get-Command nvidia-smi -ErrorAction SilentlyContinue if ($null -eq $nvidiaCommand) { Report "nvidia-smi" $false "命令不存在" $ok = $false } else { $ErrorActionPreference = 'Continue' $gpuText = & $nvidiaCommand.Source --query-gpu=name,driver_version,pstate --format=csv,noheader 2>&1 $queryExitCode = $LASTEXITCODE $ErrorActionPreference = 'Stop' if ($queryExitCode -ne 0 -or [string]::IsNullOrWhiteSpace(($gpuText -join ""))) { Report "nvidia-smi" $false (($gpuText -join " ").Trim()) $ok = $false } else { Report "nvidia-smi" $true (($gpuText -join " ").Trim()) } } try { $displayAdapters = @(Get-CimInstance Win32_VideoController | Where-Object { $_.Name -match "NVIDIA|GeForce|Quadro|Tesla" }) $healthy = @($displayAdapters | Where-Object { $_.ConfigManagerErrorCode -eq 0 }).Count -gt 0 Report "NVIDIA PnP" $healthy (($displayAdapters | ForEach-Object { "$($_.Name): code=$($_.ConfigManagerErrorCode)" }) -join "; ") $ok = $ok -and $healthy if (-not ('VdiDiagnostics.D3DProbe' -as [type])) { Add-Type -Path (Join-Path $PSScriptRoot 'probe-nvidia-d3d.cs') } $dxgi = @([VdiDiagnostics.D3DProbe]::Check()) $healthy = @($dxgi | Where-Object { $_.DeviceResult -eq 0 }).Count -gt 0 $detail = if ($dxgi.Count) { ($dxgi | ForEach-Object { '{0}: HRESULT=0x{1:X8}' -f $_.Name,$_.DeviceResult }) -join '; ' } else { 'DXGI did not enumerate an NVIDIA adapter' } Report "NVIDIA DXGI + D3D11" $healthy $detail $ok = $ok -and $healthy } catch { Report "NVIDIA DXGI + D3D11" $false $_.Exception.Message $ok = $false } if ([string]::IsNullOrWhiteSpace($SunshineLogPath)) { $candidates = @( "C:\Program Files\Sunshine\config\sunshine.log", "C:\ProgramData\Sunshine\config\sunshine.log" ) $SunshineLogPath = $candidates | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1 } if ([string]::IsNullOrWhiteSpace($SunshineLogPath) -or -not (Test-Path -LiteralPath $SunshineLogPath)) { Report "Sunshine encoder" $false "找不到 sunshine.log;不能证明实际使用 h264_nvenc" $ok = $false } else { # Encoder discovery/probing can mention both NVENC and x264. Inspect only # the most recent actual creation, with a timestamp, never the entire history. $pattern = '\[(?