# Run in native Windows PowerShell as the user who will transcode on moxexleyhp1. [CmdletBinding()] param( [string]$JobRoot = 'C:\transcode-jobs', [string]$PythonExe ) $ErrorActionPreference = 'Stop' if ($env:OS -ne 'Windows_NT') { throw 'Run this installer on Windows directly, not inside WSL.' } $WorkerScript = (Resolve-Path (Join-Path $PSScriptRoot 'windows-transcode-worker.py')).Path if (-not $PythonExe) { $PythonCommand = Get-Command python.exe -ErrorAction SilentlyContinue if (-not $PythonCommand) { $PythonCommand = Get-Command py.exe -ErrorAction SilentlyContinue } if (-not $PythonCommand) { throw 'Install Python 3.9+ for Windows, then rerun with -PythonExe C:\path\to\python.exe.' } $PythonExe = $PythonCommand.Source } # Resolve py.exe (if used) to the real interpreter for the scheduled task. $ResolvedPython = & $PythonExe -c 'import sys; assert sys.version_info >= (3, 9); print(sys.executable)' if ($LASTEXITCODE -ne 0 -or -not $ResolvedPython) { throw 'Could not run Python 3.9+. Pass -PythonExe with a working Windows interpreter.' } $PythonExe = ($ResolvedPython | Select-Object -Last 1).Trim() $FfmpegExe = (Get-Command ffmpeg.exe -ErrorAction Stop).Source $JobRoot = [System.IO.Path]::GetFullPath($JobRoot) $Inbox = Join-Path $JobRoot 'inbox' foreach ($Name in @('inbox', 'done', 'failed')) { New-Item -ItemType Directory -Force -Path (Join-Path $JobRoot $Name) | Out-Null } $TaskName = 'TMBH-TranscodeWorker' $UserId = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name $Arguments = '-u "{0}" --inbox "{1}" --ffmpeg "{2}"' -f $WorkerScript, $Inbox, $FfmpegExe $Action = New-ScheduledTaskAction -Execute $PythonExe -Argument $Arguments -WorkingDirectory $PSScriptRoot $AtLogon = New-ScheduledTaskTrigger -AtLogOn -User $UserId # No repetition duration means this trigger repeats indefinitely. $EveryFiveMinutes = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(1) -RepetitionInterval (New-TimeSpan -Minutes 5) $Principal = New-ScheduledTaskPrincipal -UserId $UserId -LogonType Interactive -RunLevel Limited $Settings = New-ScheduledTaskSettingsSet -MultipleInstances IgnoreNew -ExecutionTimeLimit ([TimeSpan]::Zero) -StartWhenAvailable -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries Register-ScheduledTask -TaskName $TaskName -Action $Action -Trigger @($AtLogon, $EveryFiveMinutes) -Principal $Principal -Settings $Settings -Description 'Poll JSON jobs and transcode with native Windows NVENC or Intel QSV.' -Force | Out-Null Start-ScheduledTask -TaskName $TaskName Write-Host "Installed and started: $TaskName (logon + every 5 minutes; duplicate starts ignored)." Write-Host "Python: $PythonExe" Write-Host "FFmpeg: $FfmpegExe" Write-Host "Worker: $WorkerScript" Write-Host "Inbox: $Inbox" Write-Host "Done: $(Join-Path $JobRoot 'done'); failed: $(Join-Path $JobRoot 'failed') with .json.err diagnostics." Write-Host 'Keep this Windows account logged on; the task uses its interactive GPU session.' Write-Host 'Keep the repository at this location, or rerun this installer after moving it.' Write-Host 'Publish jobs by writing a .tmp file, closing it, then renaming it to .json.' Write-Host "Status: Get-ScheduledTask -TaskName '$TaskName'" Write-Host "Stop: Stop-ScheduledTask -TaskName '$TaskName'" Write-Host "Manual tests: $(Join-Path $PSScriptRoot 'test-windows-worker.md')"