From 336003a6499d381d2db91bec8759a938492eebf4 Mon Sep 17 00:00:00 2001 From: public-pull Date: Sat, 16 May 2026 19:11:30 +0200 Subject: [PATCH] add install.ps1 --- install.ps1 | 184 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 184 insertions(+) create mode 100644 install.ps1 diff --git a/install.ps1 b/install.ps1 new file mode 100644 index 0000000..f1182a3 --- /dev/null +++ b/install.ps1 @@ -0,0 +1,184 @@ +# ============================================================================ +# EasyBot Windows Agent — One-Line Installer +# ============================================================================ +# +# Usage: +# powershell -ExecutionPolicy Bypass -c "irm https://raw.githubusercontent.com/pyptechnologies/easybot-windows-agent/main/install.ps1 | iex" +# +# Then configure: +# $env:EASYBOT_SERVER = "wss://your-server.com/ws/windows-agent" +# $env:EASYBOT_TOKEN = "eb_wag_..." +# easybot-windows-agent +# +# ============================================================================ + +$ErrorActionPreference = "Stop" +$InstallDir = "$env:ProgramData\EasyBot\WindowsAgent" +$ServiceName = "EasyBotWindowsAgent" +$PythonMinVersion = [version]"3.11.0" + +Write-Host "" +Write-Host "========================================" -ForegroundColor Cyan +Write-Host " EasyBot Windows Agent Installer v1.0" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan +Write-Host "" + +# ── Check admin ────────────────────────────────────────────────────────────── + +$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) +if (-not $isAdmin) { + Write-Host "[!] This installer requires administrator privileges." -ForegroundColor Yellow + Write-Host " Please run PowerShell as Administrator and try again." -ForegroundColor Yellow + exit 1 +} + +# ── Check Python ───────────────────────────────────────────────────────────── + +Write-Host "[1/5] Checking Python..." -ForegroundColor White +$pythonCmd = $null +foreach ($cmd in @("python", "python3", "py -3")) { + try { + $ver = & $cmd.Split()[0] $cmd.Split()[1..99] --version 2>&1 + if ($ver -match "Python (\d+\.\d+\.\d+)") { + $pyVer = [version]$Matches[1] + if ($pyVer -ge $PythonMinVersion) { + $pythonCmd = $cmd + Write-Host " Found Python $pyVer" -ForegroundColor Green + break + } + } + } catch {} +} + +if (-not $pythonCmd) { + Write-Host " Python >= 3.11 not found. Installing via winget..." -ForegroundColor Yellow + try { + winget install Python.Python.3.12 --accept-source-agreements --accept-package-agreements --silent + # Refresh PATH + $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User") + $pythonCmd = "python" + Write-Host " Python installed successfully" -ForegroundColor Green + } catch { + Write-Host "[X] Failed to install Python. Please install Python 3.11+ manually." -ForegroundColor Red + Write-Host " https://www.python.org/downloads/" -ForegroundColor Gray + exit 1 + } +} + +# ── Create install directory ───────────────────────────────────────────────── + +Write-Host "[2/5] Creating install directory..." -ForegroundColor White +New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null +Write-Host " $InstallDir" -ForegroundColor Gray + +# ── Install Python package ─────────────────────────────────────────────────── + +Write-Host "[3/5] Installing easybot-windows-agent package..." -ForegroundColor White +& $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -m pip install --upgrade easybot-windows-agent 2>&1 | ForEach-Object { + if ($_ -match "Successfully installed") { Write-Host " $_" -ForegroundColor Green } +} + +# If pip install from PyPI fails (package not published yet), install from local/git +if ($LASTEXITCODE -ne 0) { + Write-Host " PyPI install failed, trying direct install..." -ForegroundColor Yellow + & $pythonCmd.Split()[0] $pythonCmd.Split()[1..99] -m pip install websockets "windows-use>=0.1.0" 2>&1 | Out-Null + Write-Host " Dependencies installed" -ForegroundColor Green +} + +# ── Configure environment ──────────────────────────────────────────────────── + +Write-Host "[4/5] Configuration..." -ForegroundColor White + +$configFile = "$InstallDir\config.env" +if (Test-Path $configFile) { + Write-Host " Existing config found at $configFile" -ForegroundColor Gray +} else { + $server = Read-Host " Enter EasyBot server URL (e.g., wss://app.example.com/ws/windows-agent)" + $token = Read-Host " Enter authentication token (eb_wag_...)" + + @" +EASYBOT_SERVER=$server +EASYBOT_TOKEN=$token +LOG_LEVEL=INFO +"@ | Set-Content -Path $configFile -Encoding UTF8 + + Write-Host " Config saved to $configFile" -ForegroundColor Green +} + +# ── Install as Windows Service via nssm ────────────────────────────────────── + +Write-Host "[5/5] Installing as Windows Service..." -ForegroundColor White + +# Download nssm if not present +$nssmPath = "$InstallDir\nssm.exe" +if (-not (Test-Path $nssmPath)) { + Write-Host " Downloading nssm..." -ForegroundColor Gray + $nssmUrl = "https://nssm.cc/release/nssm-2.24.zip" + $nssmZip = "$env:TEMP\nssm.zip" + Invoke-WebRequest -Uri $nssmUrl -OutFile $nssmZip -UseBasicParsing + Expand-Archive -Path $nssmZip -DestinationPath "$env:TEMP\nssm" -Force + Copy-Item "$env:TEMP\nssm\nssm-2.24\win64\nssm.exe" $nssmPath + Remove-Item $nssmZip -Force + Remove-Item "$env:TEMP\nssm" -Recurse -Force +} + +# 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 +& $nssmPath stop $ServiceName 2>$null | Out-Null +& $nssmPath remove $ServiceName confirm 2>$null | Out-Null + +# Parse config.env for environment variables +$envVars = @() +Get-Content $configFile | ForEach-Object { + if ($_ -match "^([^#=]+)=(.*)$") { + $envVars += "$($Matches[1])=$($Matches[2])" + } +} + +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" +} + +& $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 AppExit Default Restart +& $nssmPath set $ServiceName AppRestartDelay 5000 + +Write-Host " Service installed: $ServiceName" -ForegroundColor Green + +# Start the service +& $nssmPath start $ServiceName | Out-Null +Write-Host " Service started!" -ForegroundColor Green + +Write-Host "" +Write-Host "========================================" -ForegroundColor Cyan +Write-Host " Installation Complete!" -ForegroundColor Cyan +Write-Host "========================================" -ForegroundColor Cyan +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 "" +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 ""