diff --git a/install.ps1 b/install.ps1 index 9cc2f3e..7fdde1d 100644 --- a/install.ps1 +++ b/install.ps1 @@ -131,65 +131,53 @@ LOG_LEVEL=INFO Write-Host " Config saved to $configFile" -ForegroundColor Green } -# ── Install as Windows Service via nssm ────────────────────────────────────── +# ── Install as Scheduled Task (runs in user session for desktop access) ────── -Write-Host "[5/5] Installing as Windows Service..." -ForegroundColor White +Write-Host "[5/5] Installing as Scheduled Task (user session)..." -ForegroundColor White -# Download nssm if not present +$TaskName = "EasyBotWindowsAgent" + +# Remove old nssm service if present $nssmPath = "$InstallDir\nssm.exe" -if (-not (Test-Path $nssmPath)) { - Write-Host " Downloading nssm..." -ForegroundColor Gray - $nssmUrl = "https://repo.pyp.ar/public-pull/easybot-windows-agent/raw/branch/main/bin/nssm.exe" - Invoke-WebRequest -Uri $nssmUrl -OutFile $nssmPath -UseBasicParsing -} - -# Find the easybot-windows-agent script -$agentScript = & $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -c "import shutil; print(shutil.which('easybot-windows-agent') or '')" 2>$null -if (-not $agentScript) { - # Fallback: use python -m - $agentScript = "" -} - -# Remove existing service if present (ignore errors if not installed) $ErrorActionPreference = "Continue" -& $nssmPath stop $ServiceName 2>&1 | Out-Null -& $nssmPath remove $ServiceName confirm 2>&1 | Out-Null +if (Test-Path $nssmPath) { + & $nssmPath stop $ServiceName 2>&1 | Out-Null + & $nssmPath remove $ServiceName confirm 2>&1 | Out-Null +} +# Remove old scheduled task if present +schtasks /delete /tn $TaskName /f 2>&1 | Out-Null $ErrorActionPreference = "Stop" -# Parse config.env for environment variables -$envVars = @() -Get-Content $configFile | ForEach-Object { - if ($_ -match "^([^#=]+)=(.*)$") { - $envVars += "$($Matches[1])=$($Matches[2])" +# Find Python executable +$pythonExe = & $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -c "import sys; print(sys.executable)" + +# Build a launcher script that loads config.env and runs the agent +$launcherScript = "$InstallDir\start-agent.ps1" +@" +# EasyBot Windows Agent Launcher +`$configFile = "$InstallDir\config.env" +if (Test-Path `$configFile) { + Get-Content `$configFile | ForEach-Object { + if (`$_ -match "^([^#=]+)=(.*)$") { + [System.Environment]::SetEnvironmentVariable(`$Matches[1], `$Matches[2], "Process") + } } } +& "$pythonExe" -m easybot_windows_agent.main *>> "$InstallDir\agent.log" +"@ | Set-Content -Path $launcherScript -Encoding UTF8 -if ($agentScript) { - & $nssmPath install $ServiceName $agentScript -} else { - $pythonExe = & $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -c "import sys; print(sys.executable)" - & $nssmPath install $ServiceName $pythonExe "-m" "easybot_windows_agent.main" -} +# Create scheduled task: runs at logon, highest privileges, restarts on failure +$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$launcherScript`"" +$trigger = New-ScheduledTaskTrigger -AtLogOn +$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -RestartInterval (New-TimeSpan -Seconds 30) -RestartCount 999 -StartWhenAvailable +$principal = New-ScheduledTaskPrincipal -UserId $env:USERNAME -RunLevel Highest -LogonType Interactive -& $nssmPath set $ServiceName DisplayName "EasyBot Windows Agent" -& $nssmPath set $ServiceName Description "Remote Windows GUI automation agent for EasyBot" -& $nssmPath set $ServiceName AppDirectory $InstallDir -& $nssmPath set $ServiceName AppEnvironmentExtra ($envVars -join "`n") -& $nssmPath set $ServiceName AppStdout "$InstallDir\agent.log" -& $nssmPath set $ServiceName AppStderr "$InstallDir\agent.log" -& $nssmPath set $ServiceName AppRotateFiles 1 -& $nssmPath set $ServiceName AppRotateBytes 10485760 -& $nssmPath set $ServiceName Start SERVICE_AUTO_START -& $nssmPath set $ServiceName Type SERVICE_INTERACTIVE_PROCESS -& $nssmPath set $ServiceName ObjectName "LocalSystem" -& $nssmPath set $ServiceName AppExit Default Restart -& $nssmPath set $ServiceName AppRestartDelay 5000 +Register-ScheduledTask -TaskName $TaskName -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Force | Out-Null +Write-Host " Scheduled task created: $TaskName" -ForegroundColor Green -Write-Host " Service installed: $ServiceName" -ForegroundColor Green - -# Start the service -& $nssmPath start $ServiceName | Out-Null -Write-Host " Service started!" -ForegroundColor Green +# Start it now +Start-ScheduledTask -TaskName $TaskName +Write-Host " Agent started!" -ForegroundColor Green Write-Host "" Write-Host "========================================" -ForegroundColor Cyan @@ -199,11 +187,11 @@ Write-Host "" Write-Host " Install dir: $InstallDir" -ForegroundColor Gray Write-Host " Config file: $configFile" -ForegroundColor Gray Write-Host " Log file: $InstallDir\agent.log" -ForegroundColor Gray -Write-Host " Service: $ServiceName" -ForegroundColor Gray +Write-Host " Task: $TaskName" -ForegroundColor Gray Write-Host "" Write-Host " Commands:" -ForegroundColor White -Write-Host " nssm status $ServiceName # Check status" -ForegroundColor Gray -Write-Host " nssm restart $ServiceName # Restart agent" -ForegroundColor Gray -Write-Host " nssm stop $ServiceName # Stop agent" -ForegroundColor Gray -Write-Host " nssm remove $ServiceName # Uninstall" -ForegroundColor Gray +Write-Host " schtasks /query /tn $TaskName # Check status" -ForegroundColor Gray +Write-Host " Stop-ScheduledTask -TaskName $TaskName # Stop agent" -ForegroundColor Gray +Write-Host " Start-ScheduledTask -TaskName $TaskName # Start agent" -ForegroundColor Gray +Write-Host " schtasks /delete /tn $TaskName /f # Uninstall" -ForegroundColor Gray Write-Host ""