204 lines
6.7 KiB
PowerShell
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
|
|
}
|