diff --git a/AGENTS.md b/AGENTS.md index ed617c2..27a64b7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -63,17 +63,18 @@ scripts/get-novnc.{ps1,sh} скачать noVNC scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip) scripts/list-ips.ps1 список IPv4 машины (используется run.bat) scripts/open-firewall.bat открыть порт 8080 в Windows Firewall (от админа) -scripts/set-vnc-password.bat задать VNC-пароль сервису UltraVNC (от админа; без него noVNC получает authentication rejected) scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC с паролем из run.bat (пишет только при несовпадении; UAC только при смене) — вызывается из run.bat run.bat запуск в один клик (спрашивает только пароль); синхронизирует VNC-пароль UltraVNC с введённым (см. ensure-vnc-password.ps1); если 5900 уже занят (сервис UltraVNC) — не порождает второй VNC-сервер, а подключается к существующему ``` ## Соглашения и подводные камни -- **Кодировка файлов `.bat`:** сохранять в кодировке **cp866** с окончаниями строк - **CRLF**. PowerShell `Set-Content -Encoding UTF8` добавляет BOM и пишет LF — - не использовать для `.bat`. Пиши через - `[System.IO.File]::WriteAllText(path, content -replace "(?nul` (консоль в UTF-8, иначе кириллица + в echo/set/for превратится в мусор). Проверено: `echo`, `set /p`, `for /f` и + перенаправление в файл корректно работают с кириллицей под `chcp 65001`. + Пиши через `[System.IO.File]::WriteAllText(path, content -replace "(?nul +chcp 65001 >nul cd /d "%~dp0" echo. -echo === web-vnc: VNC 㧥 === +echo === web-vnc: VNC в браузере === echo. -REM --- 1. ୨ --- +REM --- 1. Бинарник --- if exist "web-vnc.exe" goto havebin where go >nul 2>nul if not errorlevel 1 goto dogobuild -echo [訡] web-vnc.exe , Go ⠭. -echo ⠭ Go https://go.dev/dl/ ᮡ࠭ web-vnc.exe 冷. +echo [ошибка] web-vnc.exe не найден, а Go не установлен. +echo Установите Go с https://go.dev/dl/ либо положите собранный web-vnc.exe рядом. echo. pause exit /b 1 :dogobuild -echo web-vnc.exe ... +echo Собираю web-vnc.exe ... go build -o web-vnc.exe .\cmd\web-vnc if errorlevel 1 goto buildfail :havebin -REM --- 2. noVNC- --- +REM --- 2. noVNC-клиент --- if exist "internal\server\static\core\rfb.js" goto havenovnc -echo noVNC- ஥. ᪠ ... +echo noVNC-клиент ещё не встроен. Пытаюсь скачать ... powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-novnc.ps1" if errorlevel 1 goto novncfail -echo ᮡ noVNC ... +echo Пересобираю с noVNC ... go build -o web-vnc.exe .\cmd\web-vnc goto havenovnc :novncfail -echo [।०] 㤠 ᪠ noVNC ( ୥?). -echo 㧥 ஥ ࠭ ᪠. : scripts\get-novnc.ps1 +echo [предупреждение] Не удалось скачать noVNC (нет интернета?). +echo В браузере откроется страница с подсказкой. Повторите позже: scripts\get-novnc.ps1 echo. :havenovnc -REM --- 3. VNC-ࢥ (/㧪) --- +REM --- 3. VNC-сервер (поиск/загрузка) --- set "SPAWNARGS=" set "SPAWN_CMD=" if exist "vnc\winvnc.exe" goto uselocalvnc @@ -49,7 +49,7 @@ if exist "C:\Program Files\uvnc bvba\UltraVNC\winvnc.exe" goto autodetectvnc if exist "C:\Program Files (x86)\uvnc bvba\UltraVNC\winvnc.exe" goto autodetectvnc if exist "C:\Program Files\TightVNC\tvnserver.exe" goto autodetectvnc if exist "C:\Program Files (x86)\TightVNC\tvnserver.exe" goto autodetectvnc -echo VNC-ࢥ . ᪠ ⨢ UltraVNC ... +echo VNC-сервер не найден. Пытаюсь скачать портативный UltraVNC ... powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-vnc.ps1" if errorlevel 1 goto novncserver if exist "vnc\winvnc.exe" goto uselocalvnc @@ -59,75 +59,75 @@ goto novncserver 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" set "SPAWNARGS=--spawn-command "%SPAWN_CMD%"" -echo VNC-ࢥ: %SPAWN_CMD% +echo Найден локальный VNC-сервер: %SPAWN_CMD% goto vncdone :autodetectvnc -echo VNC-ࢥ ⥬ (-। ᪥). +echo VNC-сервер найден в системе (авто-определение при запуске). goto vncdone :novncserver -echo [।०] VNC-ࢥ 㤠 . -echo VNC-ࢥ ࠡ稩 ⮫ 㤥 ࠭᫨஢. -echo ⠭ UltraVNC/TightVNC : scripts\get-vnc.ps1 +echo [предупреждение] VNC-сервер не удалось получить. +echo Без VNC-сервера рабочий стол не будет транслироваться. +echo Установите UltraVNC/TightVNC вручную или повторите: scripts\get-vnc.ps1 echo. :vncdone -REM --- 4. ஫ --- +REM --- 4. Пароль --- :getpw set "PW=" -set /p "PW= ஫ 㯠: " +set /p "PW=Введите пароль доступа: " if "%PW%"=="" goto emptypw goto gotpw :emptypw -echo ஫ . +echo Пароль не может быть пустым. goto getpw :gotpw REM --- 4b. Sync UltraVNC password with the one entered (only when it differs) --- -echo ஭ ஫ UltraVNC . ᮢ ࠢ ... +echo Синхронизирую пароль UltraVNC с введённым. При несовпадении запросит права администратора... powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\ensure-vnc-password.ps1" -Password "%PW%" -if errorlevel 1 echo [।०] 㤠 ᨭ஭஢ ஫ UltraVNC - த. +if errorlevel 1 echo [предупреждение] Не удалось синхронизировать пароль UltraVNC - продолжаю. -REM --- 5. ஫ + ஫ VNC-ࢥ --- -echo ஫ ... +REM --- 5. Хэш пароля + тот же пароль для VNC-сервера --- +echo Генерирую хэш пароля ... for /f "delims=" %%i in ('web-vnc.exe --gen-hash "%PW%"') do set "HASH=%%i" if "%HASH%"=="" goto hashfail -REM ஫ 㤥 ⮬᪨ । noVNC ਧ樨 VNC-ࢥ. +REM Тот же пароль будет автоматически передан noVNC для авторизации на VNC-сервере. set "WEBVNC_VNC_PASSWORD=%PW%" set "PW=" -REM --- 6. 㯭 --- +REM --- 6. Доступные адреса --- echo. -echo === 祭 ( 8080) === +echo === Адреса для подключения (порт 8080) === echo http://localhost:8080 for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\list-ips.ps1"') do echo http://%%a:8080 echo. -echo ᫨ 㣮 設 뢠 - ࠧ 믮 -echo : scripts\open-firewall.bat +echo Если с другой машины не открывается - один раз выполните от имени +echo администратора: scripts\open-firewall.bat echo. -REM --- 7. --- -echo ᪠ web-vnc http://localhost:8080 -echo ⠭: Ctrl+C +REM --- 7. Запуск --- +echo Запускаю web-vnc на http://localhost:8080 +echo Остановить: Ctrl+C echo. REM --- 6b. 5900 already listening? -> do NOT spawn a 2nd VNC server (avoid conflict with the UltraVNC service) --- 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 ( - echo VNC-ࢥ 㦥 蠥 127.0.0.1:5900 - --spawn. + echo VNC-сервер уже слушает 127.0.0.1:5900 - подключаюсь к нему без --spawn. set "SPAWNFLAG=" ) web-vnc.exe --password-hash "%HASH%" %SPAWNARGS% %SPAWNFLAG% --listen :8080 echo. -echo ࢥ ⠭. +echo Сервер остановлен. pause exit /b :buildfail -echo ઠ 㤠. +echo Сборка не удалась. pause exit /b 1 :hashfail -echo [訡] 㤠 ᣥ஢ ஫. +echo [ошибка] Не удалось сгенерировать хэш пароля. pause exit /b 1 \ No newline at end of file diff --git a/scripts/ensure-vnc-password.ps1 b/scripts/ensure-vnc-password.ps1 index 66bb44c..69e18a4 100644 --- a/scripts/ensure-vnc-password.ps1 +++ b/scripts/ensure-vnc-password.ps1 @@ -1,59 +1,71 @@ -# ensure-vnc-password.ps1 - keep the UltraVNC service VNC password in sync -# with the password the user types in run.bat. Called from run.bat. +# ensure-vnc-password.ps1 - keep the UltraVNC VNC password in sync with the +# password the user types in run.bat. Called from run.bat. # -# It only WRITES when the password actually differs (so a normal launch with -# the same password does nothing and asks for NO admin rights). When it must -# change the password it re-launches itself elevated (one UAC prompt) and -# restarts the uvnc_service so the new password takes effect. +# It checks whether the running VNC server already ACCEPTS the given password +# (a real RFB VNC-Auth handshake against 127.0.0.1:5900 - the same mechanism +# noVNC uses). If it does, nothing happens and NO admin rights are needed. +# If it does not (or no server is up), it sets the UltraVNC service password +# to the given value (one UAC prompt) and restarts uvnc_service so it reloads. # # Usage: powershell -NoProfile -ExecutionPolicy Bypass -File ensure-vnc-password.ps1 -Password "" -# Exit codes: 0 = password matches (or was set OK); 1 = could not set it. +# Exit codes: 0 = password already accepted (or set OK); 1 = could not set it. param([Parameter(Mandatory=$true)][string]$Password) $ErrorActionPreference = "Stop" $ini = Join-Path $env:ProgramData "UltraVNC\ultravnc.ini" - function Write-Info($m){ Write-Host "ensure-vnc-password: $m" } if (-not (Test-Path $ini)) { - # No installed UltraVNC service config (e.g. portable copy / TightVNC) - nothing to sync. Write-Info "no %ProgramData%\UltraVNC\ultravnc.ini - nothing to sync." exit 0 } -# --- VNC password obfuscation: DES-ECB(key=bitrev([23,82,107,6,35,78,88,7]), pw8) + 1-byte checksum --- +# ---- bit-reverse a byte (VNC key bytes are bit-reversed) ---- function Invoke-BitRev([byte]$b){ $r=0; for($i=0;$i -lt 8;$i++){ $r = $r -bor ((($b -shr $i) -band 1) -shl (7-$i)) }; return [byte]$r } -function Get-ExpectedPasswd([string]$pw){ - $fixedkey = [byte[]](23,82,107,6,35,78,88,7) - $kr = New-Object byte[] 8; for($i=0;$i -lt 8;$i++){ $kr[$i] = Invoke-BitRev $fixedkey[$i] } - $pb = [System.Text.Encoding]::ASCII.GetBytes($pw) - if ($pb.Length -gt 8) { $pb = $pb[0..7] } - $plain = New-Object byte[] 8; for($i=0;$i -lt 8;$i++){ if($i -lt $pb.Length){ $plain[$i] = $pb[$i] } } - $des = New-Object System.Security.Cryptography.DESCryptoServiceProvider - $des.Mode = [System.Security.Cryptography.CipherMode]::ECB - $des.Padding = [System.Security.Cryptography.PaddingMode]::None - $des.Key = $kr - $cipher = $des.CreateEncryptor().TransformFinalBlock($plain,0,8) - $sum = 0; foreach($b in $cipher){ $sum = ($sum + $b) -band 0xFF } - $h = ($cipher | ForEach-Object { $_.ToString("X2") }) -join "" - return $h + $sum.ToString("X2") + +# ---- real RFB VNC-Auth probe. Returns 'ok','rejected','unreachable','noserver' ---- +function Test-VncAuth([string]$pw,[string]$target,[int]$port){ + $c = New-Object System.Net.Sockets.TcpClient + try { $c.Connect($target,$port) } catch { return 'unreachable' } + try { + $s = $c.GetStream(); $s.ReadTimeout = 8000; $s.WriteTimeout = 8000 + $rb = New-Object byte[] 64 + $got = 0 + while($got -lt 12){ $n = $s.Read($rb,$got,12-$got); if($n -le 0){ return 'unreachable' }; $got += $n } + if (-not ([System.Text.Encoding]::ASCII.GetString($rb,0,12).StartsWith("RFB "))) { return 'noserver' } + $s.Write([System.Text.Encoding]::ASCII.GetBytes("RFB 003.008`n"),0,12) + $n = $s.Read($rb,0,64); if($n -lt 1){ return 'unreachable' } + $numTypes = $rb[0] + if($numTypes -eq 0 -or $n -lt (1+$numTypes)){ return 'noserver' } + $types = $rb[1..($numTypes)] + if(-not ($types -contains 2)){ return 'noserver' } # VNC-Auth not offered (e.g. MS-Logon only) + $s.Write([byte[]](2),0,1) # choose VNC-Auth + $got = 0 + while($got -lt 16){ $n = $s.Read($rb,$got,16-$got); if($n -le 0){ return 'unreachable' }; $got += $n } + $challenge = $rb[0..15] + $pb = [System.Text.Encoding]::ASCII.GetBytes($pw) + if($pb.Length -gt 8){ $pb = $pb[0..7] } + $key = New-Object byte[] 8 + for($i=0;$i -lt 8;$i++){ $kb = if($i -lt $pb.Length){[int]$pb[$i]}else{0}; $key[$i] = Invoke-BitRev ([byte]$kb) } + $des = New-Object System.Security.Cryptography.DESCryptoServiceProvider + $des.Mode = [System.Security.Cryptography.CipherMode]::ECB + $des.Padding = [System.Security.Cryptography.PaddingMode]::None + $des.Key = $key + $resp = $des.CreateEncryptor().TransformFinalBlock($challenge,0,16) + $s.Write($resp,0,16) + $n = $s.Read($rb,0,4); if($n -lt 4){ return 'rejected' } + $status = ($rb[0]*16777216)+($rb[1]*65536)+($rb[2]*256)+$rb[3] + if($status -eq 0){ return 'ok' } else { return 'rejected' } + } finally { $c.Close() } } -function Get-CurrentPasswd{ - $line = Get-Content $ini -ErrorAction SilentlyContinue | Where-Object { $_ -match '^\s*passwd\s*=' -and $_ -notmatch 'passwd2' } | Select-Object -First 1 - if (-not $line) { return "" } - return ($line -split '=',2)[1].Trim() -} - -$expected = Get-ExpectedPasswd $Password -$current = Get-CurrentPasswd -if ($current -ieq $expected) { - Write-Info "UltraVNC password already matches - nothing to do." +$probe = Test-VncAuth $Password "127.0.0.1" 5900 +if($probe -eq 'ok'){ + Write-Info "UltraVNC already accepts this password - nothing to do." exit 0 } - -Write-Info "UltraVNC password differs (ini=$current, expected=$expected). Need to set it (admin required)." +Write-Info "UltraVNC password needs setting (probe=$probe). Need admin." # Locate UltraVNC install + password tools. $uvncDirs = @( @@ -63,64 +75,56 @@ $uvncDirs = @( "${env:ProgramFiles(x86)}\UltraVNC" ) $uvnc = $uvncDirs | Where-Object { Test-Path "$_\winvnc.exe" } | Select-Object -First 1 -if (-not $uvnc) { Write-Info "UltraVNC install not found - cannot set password."; exit 1 } +if(-not $uvnc){ Write-Info "UltraVNC install not found - cannot set password."; exit 1 } -# Are we admin? -$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) - -if (-not $isAdmin) { - Write-Info "re-launching elevated to set the password..." - $p = Start-Process -FilePath "powershell.exe" -Verb RunAs -Wait -PassThru -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","`"$PSCommandPath`"","-Password","`"$Password`"") - if ($p.ExitCode -ne 0) { Write-Info "elevated run failed (exit $($p.ExitCode))."; exit 1 } - $now = Get-CurrentPasswd - if ($now -ieq $expected) { Write-Info "password set OK."; exit 0 } - Write-Info "password still not updated after elevated run (ini=$now)."; exit 1 +function Get-IniPasswd{ + $line = Get-Content $ini -ErrorAction SilentlyContinue | Where-Object { $_ -match '^\s*passwd\s*=' -and $_ -notmatch 'passwd2' } | Select-Object -First 1 + if(-not $line){ return "" } + return ($line -split '=',2)[1].Trim() } -# --- admin path: actually set the password --- -function Set-Tool{ - param([string]$exe) - if (-not (Test-Path $exe)) { return $false } +function Invoke-SetTool([string]$exe,[string]$pw){ + if(-not (Test-Path $exe)){ return $false } try { $psi = New-Object System.Diagnostics.ProcessStartInfo - $psi.FileName = $exe - $psi.Arguments = "`"$Password`"" - $psi.UseShellExecute = $false + $psi.FileName = $exe; $psi.Arguments = "`"$pw`""; $psi.UseShellExecute = $false $p = [System.Diagnostics.Process]::Start($psi) - if (-not $p.WaitForExit(5000)) { $p.Kill() } + if(-not $p.WaitForExit(5000)){ $p.Kill() } return ($p.ExitCode -eq 0) } catch { return $false } } -$ok = $false -if (Set-Tool (Join-Path $uvnc "createpassword.exe")) { $ok = $true } -$now = Get-CurrentPasswd -if ($now -ine $expected -and (Test-Path (Join-Path $uvnc "setpasswd.exe"))) { - # fallback to setpasswd.exe "" - try { - $psi = New-Object System.Diagnostics.ProcessStartInfo - $psi.FileName = Join-Path $uvnc "setpasswd.exe" - $psi.Arguments = "`"$Password`"" - $psi.UseShellExecute = $false - $p = [System.Diagnostics.Process]::Start($psi) - if (-not $p.WaitForExit(5000)) { $p.Kill() } - } catch {} - $now = Get-CurrentPasswd +function Do-Set([string]$pw){ + $before = Get-IniPasswd + [void](Invoke-SetTool (Join-Path $uvnc "createpassword.exe") $pw) + $after = Get-IniPasswd + if($after -ieq $before){ + [void](Invoke-SetTool (Join-Path $uvnc "setpasswd.exe") $pw) + $after = Get-IniPasswd + } + if($after -ieq $before){ Write-Info "password tools did not change $ini (still $after)."; return $false } + # restart the service so the running server reloads (only if it was running) + try { $q = (& sc.exe query uvnc_service 2>$null); $running = ($q -match 'RUNNING') } catch { $running = $false } + if($running){ + Write-Info "restarting uvnc_service ..." + & net.exe stop uvnc_service 2>$null | Out-Null + & net.exe start uvnc_service 2>$null | Out-Null + } + return $true } -if ($now -ine $expected) { - Write-Info "tools did not update the password (ini=$now). Set it manually via UltraVNC Admin Properties as admin." - exit 1 -} -Write-Info "password updated in $ini." +$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) -# Restart the service so it reloads the new password. -$svc = "uvnc_service" -$svcExists = $false -try { $null = (& sc.exe query $svc 2>$null); $svcExists = ($LASTEXITCODE -eq 0) } catch {} -if ($svcExists) { - Write-Info "restarting service $svc ..." - & net.exe stop $svc 2>$null | Out-Null - & net.exe start $svc 2>$null | Out-Null +if(-not $isAdmin){ + Write-Info "re-launching elevated to set the password..." + $p = Start-Process -FilePath "powershell.exe" -Verb RunAs -Wait -PassThru -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","`"$PSCommandPath`"","-Password","`"$Password`"") + if($p.ExitCode -ne 0){ Write-Info "elevated run failed (exit $($p.ExitCode))."; exit 1 } + # confirm by re-probing (if a server is up now) + $again = Test-VncAuth $Password "127.0.0.1" 5900 + if($again -eq 'ok'){ Write-Info "password set OK."; exit 0 } + if($again -eq 'unreachable'){ Write-Info "password written; no server up to verify (will be used on next start)."; exit 0 } + Write-Info "password set but server still rejects it (probe=$again)."; exit 1 } -exit 0 \ No newline at end of file + +# admin path +if(Do-Set $Password){ Write-Info "password set OK."; exit 0 } else { exit 1 } \ No newline at end of file diff --git a/scripts/open-firewall.bat b/scripts/open-firewall.bat index 7fd2de2..b388a4d 100644 --- a/scripts/open-firewall.bat +++ b/scripts/open-firewall.bat @@ -1,16 +1,16 @@ @echo off REM ============================================================ -REM open-firewall.bat - 뢠 8080 Windows Firewall. -REM ᪠ ( ࠧ). -REM : 䠩 ᠬ ࠢ . +REM open-firewall.bat - открывает порт 8080 в Windows Firewall. +REM Запускать от имени администратора (один раз). +REM Либо запустите дважды: файл сам запросит права администратора. REM ============================================================ -chcp 866 >nul +chcp 65001 >nul cd /d "%~dp0" -REM ஢ઠ ࠢ -襭. +REM Проверка прав администратора и авто-повышение. net session >nul 2>nul if errorlevel 1 ( - echo ࠢ ... + echo Запрос прав администратора ... powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs" exit /b ) @@ -18,20 +18,20 @@ if errorlevel 1 ( set PORT=8080 set RULE=web-vnc -echo ஥ ࠢ (᫨ ) ... +echo Удаляю старое правило (если есть) ... netsh advfirewall firewall delete rule name="%RULE%" >nul 2>nul -echo ࠧ饥 ࠢ 室饣 TCP-䨪 %PORT% ... +echo Добавляю разрешающее правило для входящего TCP-трафика на порт %PORT% ... netsh advfirewall firewall add rule name="%RULE%" dir=in action=allow protocol=TCP localport=%PORT% if errorlevel 1 ( - echo [訡] 㤠 ࠢ. + echo [ошибка] Не удалось добавить правило. pause exit /b 1 ) echo. -echo ⮢. %PORT% 室 祭. -echo web-vnc 㣨 設 : -echo http://IP__:%PORT% +echo Готово. Порт %PORT% открыт для входящих подключений. +echo Теперь к web-vnc можно подключаться с других машин сети по адресу: +echo http://IP_ЭТОЙ_МАШИНЫ:%PORT% echo. pause \ No newline at end of file diff --git a/scripts/set-vnc-password.bat b/scripts/set-vnc-password.bat deleted file mode 100644 index 8a45693..0000000 --- a/scripts/set-vnc-password.bat +++ /dev/null @@ -1,109 +0,0 @@ -@echo off -REM ============================================================ -REM set-vnc-password.bat - reliably set the UltraVNC VNC password -REM for the running service (uvnc_service / LocalSystem), which -REM reads %ProgramData%\UltraVNC\ultravnc.ini. -REM -REM Runs AS ADMINISTRATOR (auto-elevates). It first tries the -REM UltraVNC CLI helpers (createpassword.exe / setpasswd.exe) and -REM VERIFIES the password actually changed in ultravnc.ini; if they -REM fail silently (as they can), it opens the UltraVNC settings GUI -REM so you can set "VNC Password" there. Then it restarts the -REM service. Use the SAME password in run.bat (ASCII, max 8 chars). -REM ============================================================ -chcp 866 >nul -cd /d "%~dp0" - -net session >nul 2>nul -if errorlevel 1 ( - echo Requesting administrator rights ... - powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs" - exit /b -) - -set "UVNC=" -for %%P in ( - "C:\Program Files\uvnc bvba\UltraVNC" - "C:\Program Files\UltraVNC" - "C:\Program Files (x86)\uvnc bvba\UltraVNC" - "C:\Program Files (x86)\UltraVNC" -) do ( - if exist "%%~P\winvnc.exe" if not defined UVNC set "UVNC=%%~P" -) -if not defined UVNC ( - echo [error] UltraVNC installation not found. - pause - exit /b 1 -) -echo UltraVNC: %UVNC% -set "INI=%ProgramData%\UltraVNC\ultravnc.ini" - -:getpw -set "PW=" -set /p "PW=Enter VNC password (ASCII, max 8 chars): " -if "%PW%"=="" ( echo Password cannot be empty. & goto getpw ) - -REM record old passwd -set "OLDPW=" -if exist "%INI%" for /f "tokens=2 delims==" %%a in ('findstr /b /i "passwd=" "%INI%" 2^>nul ^| findstr /v /i "passwd2"') do set "OLDPW=%%a" -echo Old passwd=%OLDPW% - -REM try CLI helpers, verify after each -set "DONE=0" -if exist "%UVNC%\createpassword.exe" ( - echo Trying createpassword.exe ... - "%UVNC%\createpassword.exe" "%PW%" >nul 2>nul - call :checkchanged -) -if "%DONE%"=="0" if exist "%UVNC%\setpasswd.exe" ( - echo Trying setpasswd.exe ... - "%UVNC%\setpasswd.exe" "%PW%" "%PW%" >nul 2>nul - call :checkchanged -) -if "%DONE%"=="0" ( - echo. - echo CLI helpers did not change the password file. Opening UltraVNC settings... - echo -> right-click the UltraVNC tray icon, choose Admin Properties, - echo set the "VNC Password" to: %PW% - echo -> close the settings/tray app, then come back here and press a key. - echo. - start "" "%UVNC%\winvnc.exe" - pause - call :checkchanged -) -set "PW=" -if "%DONE%"=="0" ( - echo [warn] Password still not changed in %INI%. - echo Set it manually in UltraVNC Admin Properties as administrator. - pause - exit /b 1 -) - -REM restart the service so it reloads the password -set "SVC=uvnc_service" -sc query %SVC% >nul 2>nul -if errorlevel 1 ( - echo [warn] Service '%SVC%' not found; restart winvnc manually if it runs in app mode. - goto showini -) -echo Restarting service %SVC% ... -net stop %SVC% >nul 2>nul -net start %SVC% - -:showini -echo. -echo --- %INI% --- -if exist "%INI%" type "%INI%" -echo. -echo Done. Use the SAME password in run.bat, then reconnect in the browser. -pause -exit /b - -:checkchanged -set "NEWPW=" -if exist "%INI%" for /f "tokens=2 delims==" %%a in ('findstr /b /i "passwd=" "%INI%" 2^>nul ^| findstr /v /i "passwd2"') do set "NEWPW=%%a" -if not "%NEWPW%"=="%OLDPW%" ( - echo Password file updated. New passwd=%NEWPW% - set "DONE=1" -) -goto :eof \ No newline at end of file