fix(autostart): wait for the VNC server before starting web-vnc

autostart-run.bat checked 5900 once at startup; at boot the UltraVNC service may
not be up yet, so web-vnc either spawned a 2nd VNC server (conflict) or started
serving on :8080 before the VNC server was ready, breaking browser connections.

Now autostart-run.bat polls 127.0.0.1:5900 for up to ~30s (one PowerShell loop:
TcpClient + Start-Sleep 1, exits on first accepted connection) and only then
launches web-vnc.exe -- without --spawn when 5900 already listens, or spawning a
local server (portable vnc\winvnc.exe / tvnserver.exe, else auto-detect) if it
never came up. Docs (AGENTS.md, README.md) updated.
This commit is contained in:
Codex
2026-08-05 16:14:39 +03:00
parent 9b8ee94dd5
commit f315618bfc
3 changed files with 43 additions and 21 deletions
+10 -7
View File
@@ -70,7 +70,7 @@ open-firewall.bat открыть порт 8080 в Windows Firewall (о
webvnc.conf создаётся set-password.bat; содержит HASH=<pbkdf2-хэш> и VNC_PASSWORD=<тот же пароль для noVNC>; читается run.bat и scripts/autostart-run.bat; в git не коммитится (.gitignore).
Внутренние помощники (вызываются другими скриптами, не пользователем) — в scripts/:
scripts/autostart-run.bat НЕинтерактивный launcher для автостарта (нет пауз/запросов): читает webvnc.conf, ищет только ЛОКАЛЬНЫЙ VNC-сервер (ничего не качает), запускает web-vnc.exe в foreground. Вызывается плановым заданием из install-autostart.bat.
scripts/autostart-run.bat НЕинтерактивный launcher для автостарта (нет пауз/запросов): читает webvnc.conf, ПОЛЛИТ 127.0.0.1:5900 до ~30 c (UltraVNC-сервис может ещё подниматься при загрузке) и только потом запускает web-vnc.exe — без --spawn если 5900 уже слушает, иначе спавнит локальный VNC-сервер (portable vnc\\winvnc.exe/tvnserver.exe или авто-детект). Ничего не качает на старте. Вызывается плановым заданием из install-autostart.bat.
scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC с введённым (пишет только при несовпадении; UAC только при смене) — вызывается из set-password.bat.
scripts/get-novnc.{ps1,sh} скачать noVNC
scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip)
@@ -138,12 +138,15 @@ scripts/list-ips.ps1 список IPv4 машины (использует
плановое задание `web-vnc` через `schtasks /Create /SC ONSTART /RU SYSTEM /RL HIGHEST`,
которое при загрузке ОС запускает `scripts/autostart-run.bat`.
3. `scripts/autostart-run.bat`**неинтерактивный** launcher: читает `webvnc.conf`,
при необходимости собирает `web-vnc.exe` (если есть Go), ищет только **локальный**
VNC-сервер (ничего не качает — на старте сети/интернета может не быть), и запускает
`web-vnc.exe --password-hash <HASH> --listen :8080` в foreground (задание держит
процесс живым). Если `127.0.0.1:5900` уже слушает (сервис UltraVNC) — запускает
**без** `--spawn` и **без** `--spawn-command`, подключаясь к существующему серверу
(иначе попытка породить второй VNC-сервер конфликтовала бы с сервисом).
при необходимости собирает `web-vnc.exe` (если есть Go), затем **опрашивает
`127.0.0.1:5900` до ~30 c** (один PowerShell-проект крутит цикл try/TcpClient +
`Start-Sleep 1`; выходит сразу, как только порт принял соединение) — UltraVNC-сервис
при загрузке может ещё подниматься. Если `5900` слушает — запускает
`web-vnc.exe --password-hash <HASH> --listen :8080` **без** `--spawn` (подключается
к существующему серверу, не плодя второй). Если за ~30 c не поднялось — спавнит
локальный VNC-сервер (`--spawn-command "vnc\winvnc.exe -run"` если есть portable,
иначе `--spawn` с авто-детектом) и запускает web-vnc. На старте ничего не качает.
Задание держит процесс живым в foreground.
4. Снять автостарт: `uninstall-autostart.bat` (от админа) — `schtasks /Delete`.
Замечания:
+1 -1
View File
@@ -218,7 +218,7 @@ open-firewall.bat открыть порт 8080 в Windows Firewall (о
webvnc.conf секрет: HASH= + VNC_PASSWORD= (создаётся set-password.bat, gitignored)
Внутренние помощники — в scripts/ (вызываются другими скриптами):
scripts/autostart-run.bat неинтерактивный launcher для автостарта (читает webvnc.conf)
scripts/autostart-run.bat неинтерактивный launcher для автостарта: читает webvnc.conf, ждёт 5900 до ~30 c, затем запускает web-vnc (без --spawn, если VNC уже слушает)
scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC (вызывается из set-password.bat)
scripts/get-novnc.{ps1,sh} скачать noVNC во встроенную статику
scripts/get-vnc.ps1 скачать портативный VNC-сервер (UltraVNC) в папку vnc/
+32 -13
View File
@@ -2,10 +2,12 @@
REM ============================================================
REM autostart-run.bat - non-interactive launcher used by the
REM scheduled task created by install-autostart.bat.
REM Reads the password from webvnc.conf, finds a LOCAL VNC server
REM (does NOT download anything), and starts web-vnc.exe in the
REM foreground. The task keeps the process alive and restarts it
REM on next boot.
REM Reads the password from webvnc.conf, WAITS for the VNC server
REM on 127.0.0.1:5900 (the UltraVNC service may still be starting
REM at boot), and only then starts web-vnc.exe in the foreground.
REM If no VNC server comes up, it spawns a local one (portable
REM vnc\winvnc.exe / tvnserver.exe, or auto-detected) so web-vnc
REM does not serve before the VNC server is ready.
REM Exit codes: 0 = server ran and stopped; 1 = no binary;
REM 2 = password not configured; other = web-vnc error.
REM ============================================================
@@ -33,20 +35,37 @@ if "%VNC_PW%"=="" exit /b 2
set "WEBVNC_VNC_PASSWORD=%VNC_PW%"
set "VNC_PW="
REM --- 3. VNC server (detect local only; never download at boot) ---
set "SPAWNARGS="
REM --- 3. Wait for the VNC server on 127.0.0.1:5900 ---
REM At boot the UltraVNC service (uvnc_service) may still be starting.
REM Poll up to ~30 s (one PowerShell process loops internally) so we do
REM NOT spawn a 2nd server and do NOT serve before the VNC server is
REM ready. Exits 0 as soon as 5900 accepts a connection, 1 on timeout.
echo Waiting for VNC server on 127.0.0.1:5900 (up to 30 s) ...
powershell -NoProfile -Command "for($i=0;$i -lt 30;$i++){try{$c=New-Object Net.Sockets.TcpClient('127.0.0.1',5900);$c.Close();exit 0}catch{};Start-Sleep -Seconds 1};exit 1"
if not errorlevel 1 goto vnc_up
:vnc_down
echo VNC server is not up after the wait.
set "SPAWN_CMD="
if exist "vnc\winvnc.exe" set "SPAWN_CMD=vnc\winvnc.exe -run"
if exist "vnc\tvnserver.exe" if not defined SPAWN_CMD set "SPAWN_CMD=vnc\tvnserver.exe -run"
if defined SPAWN_CMD set "SPAWNARGS=--spawn-command "%SPAWN_CMD%""
set "SPAWNFLAG=--spawn"
powershell -NoProfile -Command "try{$c=New-Object Net.Sockets.TcpClient('127.0.0.1',5900);$c.Close();exit 0}catch{exit 1}"
if not errorlevel 1 (
set "SPAWNFLAG="
if defined SPAWN_CMD goto have_spawn
set "SPAWNARGS="
)
set "SPAWNFLAG=--spawn"
echo No local VNC server; web-vnc will auto-detect and spawn one.
goto launch
:have_spawn
set "SPAWNARGS=--spawn-command "%SPAWN_CMD%""
set "SPAWNFLAG=--spawn"
echo Starting local VNC server: %SPAWN_CMD%
goto launch
:vnc_up
echo VNC server is up - connecting to it without --spawn.
set "SPAWNARGS="
set "SPAWNFLAG="
:launch
REM --- 4. Launch (foreground; the task host keeps it alive) ---
web-vnc.exe --password-hash "%HASH%" %SPAWNARGS% %SPAWNFLAG% --listen :8080
exit /b %errorlevel%