Files
soft/tools/screenshotArchive.ps1
2026-08-26 12:46:05 +03:00

204 lines
6.7 KiB
PowerShell

param(
[Parameter(Mandatory = $true)]
[string]$Archive,
[Parameter(Mandatory = $true)]
[string]$Slug,
[string]$RootDirectory = "C:\codex\catalog-screenshots",
[string]$InitialKeys = "",
[ValidateRange(1, 60)]
[int]$WaitSeconds = 8
)
$ErrorActionPreference = "Stop"
[Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()
$workDirectory = Join-Path $RootDirectory "work\$Slug"
$outputDirectory = Join-Path $RootDirectory "results"
$runner = Join-Path $PSScriptRoot "runScreenshotTask.ps1"
$javaExecutable = "C:\codex\jre\bin\javaw.exe"
function Get-NormalizedName {
param([string]$Value)
return ($Value.ToLowerInvariant() -replace '[^a-z0-9]', '')
}
function Get-CandidateScore {
param(
[System.IO.FileInfo]$File,
[string]$ProgramSlug
)
$stem = Get-NormalizedName $File.BaseName
$slugName = Get-NormalizedName $ProgramSlug
$score = [Math]::Log([Math]::Max($File.Length, 1), 2)
if ($stem -eq $slugName) {
$score += 100
}
if ($ProgramSlug -eq "qpst" -and $File.BaseName -eq "QPSTConfig") {
$score += 200
}
foreach ($token in ($ProgramSlug -split '[-_]')) {
if ($token.Length -ge 3 -and $stem.Contains((Get-NormalizedName $token))) {
$score += 15
}
}
$relativePath = $File.FullName.Substring($workDirectory.Length).TrimStart('\')
$score -= ([regex]::Matches($relativePath, '\\').Count * 2)
if ($File.BaseName -match '^(unins|uninstall|unwise|remove|register|regsvr)') {
$score -= 200
}
if ($File.BaseName -match '(setup|install|autorun|update|updater)') {
$score -= 50
}
return $score
}
function Stop-WorkDirectoryProcesses {
$directoryPrefix = $workDirectory.TrimEnd('\') + '\'
for ($attempt = 0; $attempt -lt 3; $attempt++) {
foreach ($item in Get-CimInstance Win32_Process -ErrorAction SilentlyContinue) {
if ($item.ExecutablePath -and $item.ExecutablePath.StartsWith($directoryPrefix, [System.StringComparison]::OrdinalIgnoreCase)) {
taskkill.exe /PID $item.ProcessId /T /F 2>$null | Out-Null
}
}
Start-Sleep -Milliseconds 300
}
}
New-Item -ItemType Directory -Force -Path $workDirectory, $outputDirectory | Out-Null
try {
Expand-Archive -LiteralPath $Archive -DestinationPath $workDirectory -Force
$candidates = @(
Get-ChildItem -LiteralPath $workDirectory -Recurse -File -Filter "*.exe" |
ForEach-Object {
[pscustomobject]@{
File = $_
Score = Get-CandidateScore -File $_ -ProgramSlug $Slug
}
} |
Sort-Object @{ Expression = "Score"; Descending = $true }, @{ Expression = { $_.File.Length }; Descending = $true }
)
$arguments = ""
$executable = $null
$workingDirectory = $null
if ($candidates.Count -gt 0) {
$selected = $candidates[0].File
$executable = $selected.FullName
$workingDirectory = $selected.DirectoryName
}
else {
$candidates = @(
Get-ChildItem -LiteralPath $workDirectory -Recurse -File -Filter "*.jar" |
Where-Object { $_.DirectoryName -notmatch '\\lib($|\\)' } |
ForEach-Object {
[pscustomobject]@{
File = $_
Score = Get-CandidateScore -File $_ -ProgramSlug $Slug
}
} |
Sort-Object @{ Expression = "Score"; Descending = $true }, @{ Expression = { $_.File.Length }; Descending = $true }
)
if ($candidates.Count -eq 0 -or -not (Test-Path -LiteralPath $javaExecutable)) {
[pscustomobject]@{
success = $false
reason = "no-executable"
candidates = @()
} | ConvertTo-Json -Depth 5 -Compress
exit 1
}
$selected = $candidates[0].File
$executable = $javaExecutable
$workingDirectory = $selected.DirectoryName
$arguments = "-jar `"$($selected.FullName)`""
}
$installer = $selected.Extension -ieq ".exe" -and $selected.BaseName -match '(setup|install|autorun)'
if ($installer) {
[pscustomobject]@{
success = $false
reason = "installer-only"
selected = $selected.FullName.Substring($workDirectory.Length).TrimStart('\')
installer = $true
candidates = @($candidates | Select-Object -First 10 | ForEach-Object {
[pscustomobject]@{
path = $_.File.FullName.Substring($workDirectory.Length).TrimStart('\')
size = $_.File.Length
score = [Math]::Round($_.Score, 2)
}
})
} | ConvertTo-Json -Depth 5 -Compress
exit 1
}
$winapp = "C:\codex\winapp\winapp.exe"
$builtInCapturePrograms = @("u10-u15-update-software")
$printWindowCapturePrograms = @("jadmaker")
$screenshotTool = if ($builtInCapturePrograms -contains $Slug) {
""
}
elseif ($printWindowCapturePrograms -contains $Slug) {
"printwindow"
}
elseif (Test-Path -LiteralPath $winapp) {
$winapp
}
else {
Join-Path $RootDirectory "nircmd.exe"
}
$runnerParameters = @{
Executable = $executable
Name = $Slug
OutputDirectory = $outputDirectory
WaitSeconds = $WaitSeconds
Arguments = $arguments
WorkingDirectory = $workingDirectory
InitialKeys = $InitialKeys
ScreenshotTool = $screenshotTool
}
$rawResult = & $runner @runnerParameters
$result = $rawResult | ConvertFrom-Json
[pscustomobject]@{
success = [bool]$result.success
reason = $result.reason
title = $result.title
error = $result.error
selected = $selected.FullName.Substring($workDirectory.Length).TrimStart('\')
installer = $installer
width = $result.width
height = $result.height
windows = $result.windows
candidates = @($candidates | Select-Object -First 10 | ForEach-Object {
[pscustomobject]@{
path = $_.File.FullName.Substring($workDirectory.Length).TrimStart('\')
size = $_.File.Length
score = [Math]::Round($_.Score, 2)
}
})
} | ConvertTo-Json -Depth 7 -Compress
}
catch {
[pscustomobject]@{
success = $false
reason = "error"
error = $_.Exception.Message
candidates = @()
} | ConvertTo-Json -Depth 5 -Compress
exit 1
}
finally {
Stop-WorkDirectoryProcesses
Remove-Item -LiteralPath $workDirectory -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $Archive -Force -ErrorAction SilentlyContinue
}