param( [Parameter(Mandatory = $true)] [string]$RuntimeDirectory, [switch]$EnableNetFx3, [string]$NirCmdArchive = "", [string]$ScreenshotDirectory = "C:\codex\catalog-screenshots", [switch]$Elevated ) $ErrorActionPreference = "Stop" if (-not $Elevated) { $taskName = "CodexScreenshotDependencies" $taskArguments = "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`" -RuntimeDirectory `"$RuntimeDirectory`"" if ($EnableNetFx3) { $taskArguments += " -EnableNetFx3" } if ($NirCmdArchive.Length -gt 0) { $taskArguments += " -NirCmdArchive `"$NirCmdArchive`" -ScreenshotDirectory `"$ScreenshotDirectory`"" } $taskArguments += " -Elevated" $action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $taskArguments $principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -LogonType Interactive -RunLevel Highest $settings = New-ScheduledTaskSettingsSet -ExecutionTimeLimit (New-TimeSpan -Minutes 30) -AllowStartIfOnBatteries Register-ScheduledTask -TaskName $taskName -Action $action -Principal $principal -Settings $settings -Force | Out-Null try { Start-ScheduledTask -TaskName $taskName $deadline = (Get-Date).AddMinutes(30) do { Start-Sleep -Seconds 1 $task = Get-ScheduledTask -TaskName $taskName } while ($task.State -eq "Running" -and (Get-Date) -lt $deadline) if ($task.State -eq "Running") { throw "Dependency installation timed out." } $result = (Get-ScheduledTaskInfo -TaskName $taskName).LastTaskResult if ($result -ne 0) { throw "Dependency installation failed with task result $result." } } finally { Stop-ScheduledTask -TaskName $taskName -ErrorAction SilentlyContinue Unregister-ScheduledTask -TaskName $taskName -Confirm:$false -ErrorAction SilentlyContinue } exit 0 } $systemDirectory = if (Test-Path "$env:WINDIR\SysWOW64") { "$env:WINDIR\SysWOW64" } else { "$env:WINDIR\System32" } $vbRuntime = Get-ChildItem -LiteralPath $RuntimeDirectory -Recurse -File -Filter "msvbvm50.dll" | Select-Object -First 1 if ($null -ne $vbRuntime) { Copy-Item -LiteralPath $vbRuntime.FullName -Destination $systemDirectory -Force } foreach ($control in Get-ChildItem -LiteralPath $RuntimeDirectory -Recurse -File -Filter "*.ocx") { $destination = Join-Path $systemDirectory $control.Name Copy-Item -LiteralPath $control.FullName -Destination $destination -Force $registration = Start-Process -FilePath (Join-Path $systemDirectory "regsvr32.exe") -ArgumentList "/s", $destination -Wait -PassThru if ($registration.ExitCode -ne 0) { throw "Failed to register $($control.Name): regsvr32 exit code $($registration.ExitCode)" } } if ($EnableNetFx3) { Enable-WindowsOptionalFeature -Online -FeatureName NetFx3 -All -NoRestart | Out-Null } if ($NirCmdArchive.Length -gt 0) { $temporaryDirectory = Join-Path $env:TEMP ("codex-nircmd-" + [guid]::NewGuid().ToString("N")) try { Expand-Archive -LiteralPath $NirCmdArchive -DestinationPath $temporaryDirectory -Force $nirCmd = Get-ChildItem -LiteralPath $temporaryDirectory -Recurse -File -Filter "nircmd.exe" | Select-Object -First 1 if ($null -eq $nirCmd) { throw "nircmd.exe was not found in $NirCmdArchive" } New-Item -ItemType Directory -Force -Path $ScreenshotDirectory | Out-Null Copy-Item -LiteralPath $nirCmd.FullName -Destination (Join-Path $ScreenshotDirectory "nircmd.exe") -Force } finally { Remove-Item -LiteralPath $temporaryDirectory -Recurse -Force -ErrorAction SilentlyContinue } }