@echo off rem Geek KVM screen agent - Windows installer. No administrator rights needed. rem install_agent.bat install, start now, and start at every logon rem install_agent.bat /check only check this PC, change nothing rem install_agent.bat /diagnose find out why the agent does not work: tests the USB port, the dongle, the network and the screen capture rem install_agent.bat /uninstall stop the agent and remove it rem Keep screen_agent.py, requirements.txt and this file in one folder (the receiver's "All files (.zip)"). rem Everything goes under %LOCALAPPDATA%\geek-kvm-agent; the autostart entry is one file in your Startup folder. setlocal EnableExtensions DisableDelayedExpansion set "SRC=%~dp0" set "DEST=%LOCALAPPDATA%\geek-kvm-agent" set "STARTUP=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup" set "LAUNCHER=GeekKVMAgent.vbs" set "NOPAUSE=0" if /i "%~2"=="/nopause" set "NOPAUSE=1" set "PYTHONUTF8=1" if /i "%~1"=="/uninstall" goto uninstall if /i "%~1"=="/diagnose" goto diagnose set "CHECK=0" if /i "%~1"=="/check" set "CHECK=1" set "BAD=0" echo Checking this PC... call :find_python if defined PY ( echo [ok] Python found: %PY% ) else ( echo [missing] Python 3.10 to 3.14 was not found. set "BAD=1" ) if exist "%SRC%screen_agent.py" ( echo [ok] screen_agent.py ) else ( echo [missing] screen_agent.py must be next to this file. set "BAD=1" ) if exist "%SRC%requirements.txt" ( echo [ok] requirements.txt ) else ( echo [missing] requirements.txt must be next to this file. set "BAD=1" ) if "%BAD%"=="0" goto checked if defined PY goto fail rem Only Python is missing: offer to install it. where winget >nul 2>&1 if errorlevel 1 ( echo. echo Install Python 3.12 from https://www.python.org/downloads/ and tick "Add python.exe to PATH". echo Then run this file again. goto fail ) if "%CHECK%"=="1" goto fail echo. choice /m "Install Python 3.12 now with winget" if errorlevel 2 goto fail winget install -e --id Python.Python.3.12 --accept-package-agreements --accept-source-agreements echo. echo Python is installed. Close this window and run install_agent.bat again so Windows finds it. goto done :checked if "%CHECK%"=="1" ( echo. echo Everything needed is there. Run install_agent.bat without /check to install. goto done ) echo. echo Installing into %DEST% ... call :stop_agent if not exist "%DEST%" mkdir "%DEST%" copy /y "%SRC%screen_agent.py" "%DEST%\" >nul || goto fail copy /y "%SRC%requirements.txt" "%DEST%\" >nul || goto fail if not exist "%DEST%\.venv\Scripts\python.exe" ( echo Creating the Python environment... %PY% -m venv "%DEST%\.venv" || goto fail ) echo Installing the packages (a few minutes: aiortc is large)... "%DEST%\.venv\Scripts\python.exe" -m pip install --quiet --disable-pip-version-check -r "%DEST%\requirements.txt" || goto fail rem run_agent.bat: start the agent, and start it again 5 seconds after it stops; the log is agent.log (the previous one becomes agent.old.log) set "RUN=%DEST%\run_agent.bat" > "%RUN%" echo @echo off >> "%RUN%" echo set PYTHONUTF8=1 >> "%RUN%" echo cd /d "%%~dp0" >> "%RUN%" echo if exist agent.log move /y agent.log agent.old.log ^>nul >> "%RUN%" echo :loop >> "%RUN%" echo ".venv\Scripts\python.exe" -u screen_agent.py ^>^> agent.log 2^>^&1 >> "%RUN%" echo ping -n 6 127.0.0.1 ^>nul >> "%RUN%" echo goto loop rem GeekKVMAgent.vbs: runs run_agent.bat without a console window. It lives in the Startup folder too, so the agent starts at every logon rem inside your own desktop session (the only place a program can capture the screen). set "VBS=%DEST%\%LAUNCHER%" > "%VBS%" echo CreateObject^("WScript.Shell"^).Run """%RUN%""", 0, False copy /y "%VBS%" "%STARTUP%\%LAUNCHER%" >nul || goto fail wscript.exe "%VBS%" echo. echo Installed and started. The screen appears on the dongle's web page within a few seconds. echo Plug the dongle into this PC with USB first: the agent asks it for its address over USB. echo If it does not work: install_agent.bat /diagnose (and send the output) echo Log file: %DEST%\agent.log echo Autostart: %STARTUP%\%LAUNCHER% echo Remove: install_agent.bat /uninstall echo Note: Windows cannot share the screen while it is locked or at a UAC prompt; the keyboard still works then. goto done :diagnose rem Stops the running agent (it holds the dongle's USB port), tests everything the agent needs, shows the end of agent.log, starts the agent again. set "WASRUNNING=0" if exist "%DEST%\run_agent.bat" set "WASRUNNING=1" call :stop_agent if exist "%DEST%\.venv\Scripts\python.exe" goto diag_installed call :find_python if not defined PY goto diag_nopython echo Not installed yet: testing with %PY% and the files next to this one. echo. %PY% "%SRC%screen_agent.py" --diagnose goto diag_log :diag_installed "%DEST%\.venv\Scripts\python.exe" "%DEST%\screen_agent.py" --diagnose goto diag_log :diag_nopython echo Python 3.10 to 3.14 is not installed: that alone explains it. Run install_agent.bat first. goto fail :diag_log echo. echo ---- the end of %DEST%\agent.log ---- if not exist "%DEST%\agent.log" goto diag_nolog powershell -NoProfile -Command "Get-Content -Tail 25 -LiteralPath '%DEST%\agent.log'" goto diag_restart :diag_nolog echo There is no agent.log yet. :diag_restart if "%WASRUNNING%"=="0" goto done wscript.exe "%DEST%\%LAUNCHER%" echo. echo The agent was started again. goto done :uninstall call :stop_agent del /q "%STARTUP%\%LAUNCHER%" >nul 2>&1 if exist "%DEST%" rmdir /s /q "%DEST%" echo Removed. The token the agent learned from the dongle stays in %USERPROFILE%\.config\esp32s3geek_kvm if you want to delete it too. goto done :find_python rem Python 3.10 to 3.14, the newest first. Every package in requirements.txt (aiortc and its PyAV, cryptography, Pillow...) ships rem ready-made wheels for these on 64-bit Windows, so nothing has to be compiled. Sets PY (empty when none is found). set "PY=" for %%V in (3.14 3.13 3.12 3.11 3.10) do ( if not defined PY ( py -%%V -c "import sys" >nul 2>&1 && set "PY=py -%%V" ) ) if not defined PY ( python -c "import sys; sys.exit(0 if (3, 10) <= sys.version_info[:2] <= (3, 14) else 1)" >nul 2>&1 && set "PY=python" ) exit /b 0 :stop_agent rem Stop the agent and its restart loop (every process whose command line mentions the install folder). powershell -NoProfile -Command "Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -like '*geek-kvm-agent*' -and $_.ProcessId -ne $PID } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue }" >nul 2>&1 exit /b 0 :fail echo. echo Not installed. if "%NOPAUSE%"=="0" pause exit /b 1 :done echo. if "%NOPAUSE%"=="0" pause exit /b 0