polish: UTF-8 batch scripts, drop redundant set-vnc-password, robust vnc password probe

- run.bat / open-firewall.bat: UTF-8 (no BOM) + chcp 65001 instead of cp866/chcp 866.
- scripts/set-vnc-password.bat: removed (run.bat syncs the UltraVNC password via ensure-vnc-password.ps1).
- scripts/ensure-vnc-password.ps1: use a real RFB VNC-Auth probe to 127.0.0.1:5900
  to decide if the password already matches (no UAC when it does); set via
  createpassword/setpasswd + service restart only when it differs. Works for
  any password length (no stored-password encoding assumptions).
- AGENTS.md: .bat encoding convention updated to UTF-8/chcp 65001; drop set-vnc-password refs.
This commit is contained in:
Codex
2026-07-30 20:03:43 +03:00
parent 6a1ee64b14
commit db4f33f725
5 changed files with 144 additions and 248 deletions
+7 -6
View File
@@ -63,17 +63,18 @@ scripts/get-novnc.{ps1,sh} скачать noVNC
scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip) scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip)
scripts/list-ips.ps1 список IPv4 машины (используется run.bat) scripts/list-ips.ps1 список IPv4 машины (используется run.bat)
scripts/open-firewall.bat открыть порт 8080 в Windows Firewall (от админа) 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 scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC с паролем из run.bat (пишет только при несовпадении; UAC только при смене) — вызывается из run.bat
run.bat запуск в один клик (спрашивает только пароль); синхронизирует VNC-пароль UltraVNC с введённым (см. ensure-vnc-password.ps1); если 5900 уже занят (сервис UltraVNC) — не порождает второй VNC-сервер, а подключается к существующему run.bat запуск в один клик (спрашивает только пароль); синхронизирует VNC-пароль UltraVNC с введённым (см. ensure-vnc-password.ps1); если 5900 уже занят (сервис UltraVNC) — не порождает второй VNC-сервер, а подключается к существующему
``` ```
## Соглашения и подводные камни ## Соглашения и подводные камни
- **Кодировка файлов `.bat`:** сохранять в кодировке **cp866** с окончаниями строк - **Кодировка файлов `.bat`:** **UTF-8 без BOM**, окончания строк **CRLF**, и первой
**CRLF**. PowerShell `Set-Content -Encoding UTF8` добавляет BOM и пишет LF — командой после `@echo off``chcp 65001 >nul` (консоль в UTF-8, иначе кириллица
не использовать для `.bat`. Пиши через в echo/set/for превратится в мусор). Проверено: `echo`, `set /p`, `for /f` и
`[System.IO.File]::WriteAllText(path, content -replace "(?<!\r)\n","`r`n", [Text.Encoding]::GetEncoding(866))`. перенаправление в файл корректно работают с кириллицей под `chcp 65001`.
Пиши через `[System.IO.File]::WriteAllText(path, content -replace "(?<!\r)\n","`r`n", [Text.UTF8Encoding]::new($false))`.
(BOM не ставить — ломает первую строку `@echo off` на старых Windows.)
- **Go-файлы:** UTF-8 **без BOM**, LF. То же самое правило — не использовать - **Go-файлы:** UTF-8 **без BOM**, LF. То же самое правило — не использовать
`Set-Content -Encoding UTF8` (ставит BOM). Используй `Set-Content -Encoding UTF8` (ставит BOM). Используй
`[System.IO.File]::WriteAllText(path, content, [Text.UTF8Encoding]::new($false))`. `[System.IO.File]::WriteAllText(path, content, [Text.UTF8Encoding]::new($false))`.
@@ -102,5 +103,5 @@ run.bat запуск в один клик (спрашивае
`%ProgramData%\UltraVNC\ultravnc.ini`; задать его обычным пользователем через `%ProgramData%\UltraVNC\ultravnc.ini`; задать его обычным пользователем через
tray-иконку молча не получается (нет прав на запись). tray-иконку молча не получается (нет прав на запись).
`run.bat` синхронизирует этот пароль сам через `scripts/ensure-vnc-password.ps1` `run.bat` синхронизирует этот пароль сам через `scripts/ensure-vnc-password.ps1`
(пишет только при несовпадении, UAC только при смене; вручную — `scripts/set-vnc-password.bat` от админа). VNC-пароль = первые 8 байт, (пишет только при несовпадении; UAC только при смене пароля). VNC-пароль = первые 8 байт,
поэтому используй ASCII-пароль <= 8 символов и там, и в `run.bat`. поэтому используй ASCII-пароль <= 8 символов и там, и в `run.bat`.
+38 -38
View File
@@ -1,44 +1,44 @@
@echo off @echo off
REM ============================================================ REM ============================================================
REM web-vnc launcher - § ¯ã᪠¢ ®¤¨­ ª«¨ª. ‘¯à è¨¢ ¥â ⮫쪮 ¯ à®«ì. REM web-vnc launcher - запуск в один клик. Спрашивает только пароль.
REM ============================================================ REM ============================================================
chcp 866 >nul chcp 65001 >nul
cd /d "%~dp0" cd /d "%~dp0"
echo. echo.
echo === web-vnc: VNC ¢ ¡à ã§¥à¥ === echo === web-vnc: VNC в браузере ===
echo. echo.
REM --- 1. ¨­ à­¨ª --- REM --- 1. Бинарник ---
if exist "web-vnc.exe" goto havebin if exist "web-vnc.exe" goto havebin
where go >nul 2>nul where go >nul 2>nul
if not errorlevel 1 goto dogobuild if not errorlevel 1 goto dogobuild
echo [®è¨¡ª ] web-vnc.exe ­¥ ­ ©¤¥­,   Go ­¥ ãáâ ­®¢«¥­. echo [ошибка] web-vnc.exe не найден, а Go не установлен.
echo “áâ ­®¢¨â¥ Go á https://go.dev/dl/ «¨¡® ¯®«®¦¨â¥ ᮡ࠭­ë© web-vnc.exe à冷¬. echo Установите Go с https://go.dev/dl/ либо положите собранный web-vnc.exe рядом.
echo. echo.
pause pause
exit /b 1 exit /b 1
:dogobuild :dogobuild
echo ‘®¡¨à î web-vnc.exe ... echo Собираю web-vnc.exe ...
go build -o web-vnc.exe .\cmd\web-vnc go build -o web-vnc.exe .\cmd\web-vnc
if errorlevel 1 goto buildfail if errorlevel 1 goto buildfail
:havebin :havebin
REM --- 2. noVNC-ª«¨¥­â --- REM --- 2. noVNC-клиент ---
if exist "internal\server\static\core\rfb.js" goto havenovnc if exist "internal\server\static\core\rfb.js" goto havenovnc
echo noVNC-ª«¨¥­â ¥éñ ­¥ ¢áâ஥­. ëâ îáì ᪠ç âì ... echo noVNC-клиент ещё не встроен. Пытаюсь скачать ...
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-novnc.ps1" powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-novnc.ps1"
if errorlevel 1 goto novncfail if errorlevel 1 goto novncfail
echo ¥à¥á®¡¨à î á noVNC ... echo Пересобираю с noVNC ...
go build -o web-vnc.exe .\cmd\web-vnc go build -o web-vnc.exe .\cmd\web-vnc
goto havenovnc goto havenovnc
:novncfail :novncfail
echo [¯à¥¤ã¯à¥¦¤¥­¨¥] ¥ 㤠«®áì ᪠ç âì noVNC (­¥â ¨­â¥à­¥â ?). echo [предупреждение] Не удалось скачать noVNC (нет интернета?).
echo ‚ ¡à ã§¥à¥ ®âªà®¥âáï áâà ­¨æ  á ¯®¤áª §ª®©. ®¢â®à¨â¥ ¯®§¦¥: scripts\get-novnc.ps1 echo В браузере откроется страница с подсказкой. Повторите позже: scripts\get-novnc.ps1
echo. echo.
:havenovnc :havenovnc
REM --- 3. VNC-á¥à¢¥à (¯®¨áª/§ £à㧪 ) --- REM --- 3. VNC-сервер (поиск/загрузка) ---
set "SPAWNARGS=" set "SPAWNARGS="
set "SPAWN_CMD=" set "SPAWN_CMD="
if exist "vnc\winvnc.exe" goto uselocalvnc 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 (x86)\uvnc bvba\UltraVNC\winvnc.exe" goto autodetectvnc
if exist "C:\Program Files\TightVNC\tvnserver.exe" goto autodetectvnc if exist "C:\Program Files\TightVNC\tvnserver.exe" goto autodetectvnc
if exist "C:\Program Files (x86)\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" powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-vnc.ps1"
if errorlevel 1 goto novncserver if errorlevel 1 goto novncserver
if exist "vnc\winvnc.exe" goto uselocalvnc 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\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 exist "vnc\tvnserver.exe" if not defined SPAWN_CMD set "SPAWN_CMD=vnc\tvnserver.exe -run"
set "SPAWNARGS=--spawn-command "%SPAWN_CMD%"" set "SPAWNARGS=--spawn-command "%SPAWN_CMD%""
echo  ©¤¥­ «®ª «ì­ë© VNC-á¥à¢¥à: %SPAWN_CMD% echo Найден локальный VNC-сервер: %SPAWN_CMD%
goto vncdone goto vncdone
:autodetectvnc :autodetectvnc
echo VNC-á¥à¢¥à ­ ©¤¥­ ¢ á¨á⥬¥ ( ¢â®-®¯à¥¤¥«¥­¨¥ ¯à¨ § ¯ã᪥). echo VNC-сервер найден в системе (авто-определение при запуске).
goto vncdone goto vncdone
:novncserver :novncserver
echo [¯à¥¤ã¯à¥¦¤¥­¨¥] VNC-á¥à¢¥à ­¥ 㤠«®áì ¯®«ãç¨âì. echo [предупреждение] VNC-сервер не удалось получить.
echo ¥§ VNC-á¥à¢¥à  à ¡®ç¨© á⮫ ­¥ ¡ã¤¥â â࠭᫨஢ âìáï. echo Без VNC-сервера рабочий стол не будет транслироваться.
echo “áâ ­®¢¨â¥ UltraVNC/TightVNC ¢àãç­ãî ¨«¨ ¯®¢â®à¨â¥: scripts\get-vnc.ps1 echo Установите UltraVNC/TightVNC вручную или повторите: scripts\get-vnc.ps1
echo. echo.
:vncdone :vncdone
REM --- 4.  à®«ì --- REM --- 4. Пароль ---
:getpw :getpw
set "PW=" set "PW="
set /p "PW=‚¢¥¤¨â¥ ¯ à®«ì ¤®áâ㯠: " set /p "PW=Введите пароль доступа: "
if "%PW%"=="" goto emptypw if "%PW%"=="" goto emptypw
goto gotpw goto gotpw
:emptypw :emptypw
echo  à®«ì ­¥ ¬®¦¥â ¡ëâì ¯ãáâë¬. echo Пароль не может быть пустым.
goto getpw goto getpw
:gotpw :gotpw
REM --- 4b. Sync UltraVNC password with the one entered (only when it differs) --- 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%" 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-á¥à¢¥à  --- REM --- 5. Хэш пароля + тот же пароль для VNC-сервера ---
echo ƒ¥­¥à¨àãî åíè ¯ à®«ï ... echo Генерирую хэш пароля ...
for /f "delims=" %%i in ('web-vnc.exe --gen-hash "%PW%"') do set "HASH=%%i" for /f "delims=" %%i in ('web-vnc.exe --gen-hash "%PW%"') do set "HASH=%%i"
if "%HASH%"=="" goto hashfail if "%HASH%"=="" goto hashfail
REM ’®â ¦¥ ¯ à®«ì ¡ã¤¥â  ¢â®¬ â¨ç¥áª¨ ¯¥à¥¤ ­ noVNC ¤«ï  ¢â®à¨§ æ¨¨ ­  VNC-á¥à¢¥à¥. REM Тот же пароль будет автоматически передан noVNC для авторизации на VNC-сервере.
set "WEBVNC_VNC_PASSWORD=%PW%" set "WEBVNC_VNC_PASSWORD=%PW%"
set "PW=" set "PW="
REM --- 6. „®áâã¯­ë¥  ¤à¥á  --- REM --- 6. Доступные адреса ---
echo. echo.
echo === €¤à¥á  ¤«ï ¯®¤ª«î祭¨ï (¯®àâ 8080) === echo === Адреса для подключения (порт 8080) ===
echo http://localhost:8080 echo http://localhost:8080
for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\list-ips.ps1"') do echo http://%%a:8080 for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\list-ips.ps1"') do echo http://%%a:8080
echo. echo.
echo …᫨ á ¤à㣮© ¬ è¨­ë ­¥ ®âªà뢠¥âáï - ®¤¨­ à § ¢ë¯®«­¨â¥ ®â ¨¬¥­¨ echo Если с другой машины не открывается - один раз выполните от имени
echo  ¤¬¨­¨áâà â®à : scripts\open-firewall.bat echo администратора: scripts\open-firewall.bat
echo. echo.
REM --- 7. ‡ ¯ã᪠--- REM --- 7. Запуск ---
echo ‡ ¯ã᪠î web-vnc ­  http://localhost:8080 echo Запускаю web-vnc на http://localhost:8080
echo Žáâ ­®¢¨âì: Ctrl+C echo Остановить: Ctrl+C
echo. echo.
REM --- 6b. 5900 already listening? -> do NOT spawn a 2nd VNC server (avoid conflict with the UltraVNC service) --- REM --- 6b. 5900 already listening? -> do NOT spawn a 2nd VNC server (avoid conflict with the UltraVNC service) ---
set "SPAWNFLAG=--spawn" 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}" 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 ( if not errorlevel 1 (
echo VNC-á¥à¢¥à 㦥 á«ãè ¥â 127.0.0.1:5900 - ¯®¤ª«îç îáì ª ­¥¬ã ¡¥§ --spawn. echo VNC-сервер уже слушает 127.0.0.1:5900 - подключаюсь к нему без --spawn.
set "SPAWNFLAG=" set "SPAWNFLAG="
) )
web-vnc.exe --password-hash "%HASH%" %SPAWNARGS% %SPAWNFLAG% --listen :8080 web-vnc.exe --password-hash "%HASH%" %SPAWNARGS% %SPAWNFLAG% --listen :8080
echo. echo.
echo ‘¥à¢¥à ®áâ ­®¢«¥­. echo Сервер остановлен.
pause pause
exit /b exit /b
:buildfail :buildfail
echo ‘¡®àª  ­¥ 㤠« áì. echo Сборка не удалась.
pause pause
exit /b 1 exit /b 1
:hashfail :hashfail
echo [®è¨¡ª ] ¥ 㤠«®áì ᣥ­¥à¨à®¢ âì åíè ¯ à®«ï. echo [ошибка] Не удалось сгенерировать хэш пароля.
pause pause
exit /b 1 exit /b 1
+79 -75
View File
@@ -1,59 +1,71 @@
# ensure-vnc-password.ps1 - keep the UltraVNC service VNC password in sync # ensure-vnc-password.ps1 - keep the UltraVNC VNC password in sync with the
# with the password the user types in run.bat. Called from run.bat. # password the user types in run.bat. Called from run.bat.
# #
# It only WRITES when the password actually differs (so a normal launch with # It checks whether the running VNC server already ACCEPTS the given password
# the same password does nothing and asks for NO admin rights). When it must # (a real RFB VNC-Auth handshake against 127.0.0.1:5900 - the same mechanism
# change the password it re-launches itself elevated (one UAC prompt) and # noVNC uses). If it does, nothing happens and NO admin rights are needed.
# restarts the uvnc_service so the new password takes effect. # 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 "<pw>" # Usage: powershell -NoProfile -ExecutionPolicy Bypass -File ensure-vnc-password.ps1 -Password "<pw>"
# 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) param([Parameter(Mandatory=$true)][string]$Password)
$ErrorActionPreference = "Stop" $ErrorActionPreference = "Stop"
$ini = Join-Path $env:ProgramData "UltraVNC\ultravnc.ini" $ini = Join-Path $env:ProgramData "UltraVNC\ultravnc.ini"
function Write-Info($m){ Write-Host "ensure-vnc-password: $m" } function Write-Info($m){ Write-Host "ensure-vnc-password: $m" }
if (-not (Test-Path $ini)) { 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." Write-Info "no %ProgramData%\UltraVNC\ultravnc.ini - nothing to sync."
exit 0 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 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) # ---- real RFB VNC-Auth probe. Returns 'ok','rejected','unreachable','noserver' ----
$kr = New-Object byte[] 8; for($i=0;$i -lt 8;$i++){ $kr[$i] = Invoke-BitRev $fixedkey[$i] } 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) $pb = [System.Text.Encoding]::ASCII.GetBytes($pw)
if($pb.Length -gt 8){ $pb = $pb[0..7] } 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] } } $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 = New-Object System.Security.Cryptography.DESCryptoServiceProvider
$des.Mode = [System.Security.Cryptography.CipherMode]::ECB $des.Mode = [System.Security.Cryptography.CipherMode]::ECB
$des.Padding = [System.Security.Cryptography.PaddingMode]::None $des.Padding = [System.Security.Cryptography.PaddingMode]::None
$des.Key = $kr $des.Key = $key
$cipher = $des.CreateEncryptor().TransformFinalBlock($plain,0,8) $resp = $des.CreateEncryptor().TransformFinalBlock($challenge,0,16)
$sum = 0; foreach($b in $cipher){ $sum = ($sum + $b) -band 0xFF } $s.Write($resp,0,16)
$h = ($cipher | ForEach-Object { $_.ToString("X2") }) -join "" $n = $s.Read($rb,0,4); if($n -lt 4){ return 'rejected' }
return $h + $sum.ToString("X2") $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{ $probe = Test-VncAuth $Password "127.0.0.1" 5900
$line = Get-Content $ini -ErrorAction SilentlyContinue | Where-Object { $_ -match '^\s*passwd\s*=' -and $_ -notmatch 'passwd2' } | Select-Object -First 1 if($probe -eq 'ok'){
if (-not $line) { return "" } Write-Info "UltraVNC already accepts this password - nothing to do."
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."
exit 0 exit 0
} }
Write-Info "UltraVNC password needs setting (probe=$probe). Need admin."
Write-Info "UltraVNC password differs (ini=$current, expected=$expected). Need to set it (admin required)."
# Locate UltraVNC install + password tools. # Locate UltraVNC install + password tools.
$uvncDirs = @( $uvncDirs = @(
@@ -65,62 +77,54 @@ $uvncDirs = @(
$uvnc = $uvncDirs | Where-Object { Test-Path "$_\winvnc.exe" } | Select-Object -First 1 $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? function Get-IniPasswd{
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) $line = Get-Content $ini -ErrorAction SilentlyContinue | Where-Object { $_ -match '^\s*passwd\s*=' -and $_ -notmatch 'passwd2' } | Select-Object -First 1
if(-not $line){ return "" }
if (-not $isAdmin) { return ($line -split '=',2)[1].Trim()
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
} }
# --- admin path: actually set the password --- function Invoke-SetTool([string]$exe,[string]$pw){
function Set-Tool{
param([string]$exe)
if(-not (Test-Path $exe)){ return $false } if(-not (Test-Path $exe)){ return $false }
try { try {
$psi = New-Object System.Diagnostics.ProcessStartInfo $psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = $exe $psi.FileName = $exe; $psi.Arguments = "`"$pw`""; $psi.UseShellExecute = $false
$psi.Arguments = "`"$Password`""
$psi.UseShellExecute = $false
$p = [System.Diagnostics.Process]::Start($psi) $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) return ($p.ExitCode -eq 0)
} catch { return $false } } catch { return $false }
} }
$ok = $false function Do-Set([string]$pw){
if (Set-Tool (Join-Path $uvnc "createpassword.exe")) { $ok = $true } $before = Get-IniPasswd
$now = Get-CurrentPasswd [void](Invoke-SetTool (Join-Path $uvnc "createpassword.exe") $pw)
if ($now -ine $expected -and (Test-Path (Join-Path $uvnc "setpasswd.exe"))) { $after = Get-IniPasswd
# fallback to setpasswd.exe "<pw>" if($after -ieq $before){
try { [void](Invoke-SetTool (Join-Path $uvnc "setpasswd.exe") $pw)
$psi = New-Object System.Diagnostics.ProcessStartInfo $after = Get-IniPasswd
$psi.FileName = Join-Path $uvnc "setpasswd.exe" }
$psi.Arguments = "`"$Password`"" if($after -ieq $before){ Write-Info "password tools did not change $ini (still $after)."; return $false }
$psi.UseShellExecute = $false # restart the service so the running server reloads (only if it was running)
$p = [System.Diagnostics.Process]::Start($psi) try { $q = (& sc.exe query uvnc_service 2>$null); $running = ($q -match 'RUNNING') } catch { $running = $false }
if (-not $p.WaitForExit(5000)) { $p.Kill() } if($running){
} catch {} Write-Info "restarting uvnc_service ..."
$now = Get-CurrentPasswd & net.exe stop uvnc_service 2>$null | Out-Null
& net.exe start uvnc_service 2>$null | Out-Null
}
return $true
} }
if ($now -ine $expected) { $isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
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."
# Restart the service so it reloads the new password. if(-not $isAdmin){
$svc = "uvnc_service" Write-Info "re-launching elevated to set the password..."
$svcExists = $false $p = Start-Process -FilePath "powershell.exe" -Verb RunAs -Wait -PassThru -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","`"$PSCommandPath`"","-Password","`"$Password`"")
try { $null = (& sc.exe query $svc 2>$null); $svcExists = ($LASTEXITCODE -eq 0) } catch {} if($p.ExitCode -ne 0){ Write-Info "elevated run failed (exit $($p.ExitCode))."; exit 1 }
if ($svcExists) { # confirm by re-probing (if a server is up now)
Write-Info "restarting service $svc ..." $again = Test-VncAuth $Password "127.0.0.1" 5900
& net.exe stop $svc 2>$null | Out-Null if($again -eq 'ok'){ Write-Info "password set OK."; exit 0 }
& net.exe start $svc 2>$null | Out-Null 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
# admin path
if(Do-Set $Password){ Write-Info "password set OK."; exit 0 } else { exit 1 }
+12 -12
View File
@@ -1,16 +1,16 @@
@echo off @echo off
REM ============================================================ REM ============================================================
REM open-firewall.bat - ®âªà뢠¥â ¯®àâ 8080 ¢ Windows Firewall. REM open-firewall.bat - открывает порт 8080 в Windows Firewall.
REM ‡ ¯ã᪠âì ®â ¨¬¥­¨  ¤¬¨­¨áâà â®à  (®¤¨­ à §). REM Запускать от имени администратора (один раз).
REM ‹¨¡® § ¯ãáâ¨â¥ ¤¢ ¦¤ë: ä ©« á ¬ § ¯à®á¨â ¯à ¢   ¤¬¨­¨áâà â®à . REM Либо запустите дважды: файл сам запросит права администратора.
REM ============================================================ REM ============================================================
chcp 866 >nul chcp 65001 >nul
cd /d "%~dp0" cd /d "%~dp0"
REM ஢¥àª  ¯à ¢  ¤¬¨­¨áâà â®à  ¨  ¢â®-¯®¢ë襭¨¥. REM Проверка прав администратора и авто-повышение.
net session >nul 2>nul net session >nul 2>nul
if errorlevel 1 ( if errorlevel 1 (
echo ‡ ¯à®á ¯à ¢  ¤¬¨­¨áâà â®à  ... echo Запрос прав администратора ...
powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs" powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
exit /b exit /b
) )
@@ -18,20 +18,20 @@ if errorlevel 1 (
set PORT=8080 set PORT=8080
set RULE=web-vnc set RULE=web-vnc
echo “¤ «ïî áâ à®¥ ¯à ¢¨«® (¥á«¨ ¥áâì) ... echo Удаляю старое правило (если есть) ...
netsh advfirewall firewall delete rule name="%RULE%" >nul 2>nul 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% netsh advfirewall firewall add rule name="%RULE%" dir=in action=allow protocol=TCP localport=%PORT%
if errorlevel 1 ( if errorlevel 1 (
echo [®è¨¡ª ] ¥ 㤠«®áì ¤®¡ ¢¨âì ¯à ¢¨«®. echo [ошибка] Не удалось добавить правило.
pause pause
exit /b 1 exit /b 1
) )
echo. echo.
echo ƒ®â®¢®. ®àâ %PORT% ®âªàëâ ¤«ï ¢å®¤ïé¨å ¯®¤ª«î祭¨©. echo Готово. Порт %PORT% открыт для входящих подключений.
echo ’¥¯¥àì ª web-vnc ¬®¦­® ¯®¤ª«îç âìáï á ¤àã£¨å ¬ è¨­ á¥â¨ ¯®  ¤à¥áã: echo Теперь к web-vnc можно подключаться с других машин сети по адресу:
echo http://IP_’މ_Œ€˜ˆ:%PORT% echo http://IP_ЭТОЙ_МАШИНЫ:%PORT%
echo. echo.
pause pause
-109
View File
@@ -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