@echo off setlocal EnableExtensions REM ========================================================================== REM start_all.bat - start the Arm update server (server.py on :8888), REM Tailscale Funnel and a Cloudflare quick tunnel. REM REM start_all.bat start everything (safe to run again - skips what is already running) REM start_all.bat /install also start it automatically every time you log in REM start_all.bat /startup (used by the login entry: same as normal, but no pause at the end) REM ========================================================================== set "ARM=%~dp0" if "%ARM:~-1%"=="\" set "ARM=%ARM:~0,-1%" set "PORT=8888" set "PYW=C:\Python314\pythonw.exe" set "CFLOG=%ARM%\cloudflared.log" set "LANURL=http://192.168.0.86:8888" if /i "%~1"=="/install" goto install echo ========================================== echo Starting All Arm Server Services echo ========================================== REM ---------------------------------------------------------------- 1. server.py echo [1/4] Python HTTP server (port %PORT%)... call :listening if not errorlevel 1 ( echo already running - skipped goto funnel ) if not exist "%PYW%" ( echo ERROR: %PYW% not found - edit PYW at the top of this file goto funnel ) powershell -NoProfile -Command "Invoke-CimMethod -ClassName Win32_Process -MethodName Create -Arguments @{ CommandLine = '\"%PYW%\" \"%ARM%\server.py\"'; CurrentDirectory = '%ARM%' } | Out-Null" set /a n=0 :waitsrv call :listening if not errorlevel 1 ( echo started goto funnel ) set /a n+=1 if %n% geq 15 ( echo WARNING: nothing is listening on port %PORT% after 15s - check server.py goto funnel ) timeout /t 1 /nobreak >nul goto waitsrv REM ---------------------------------------------------------------- 2. Tailscale Funnel :funnel echo [2/4] Tailscale Funnel... set "TSHOST=" where tailscale >nul 2>&1 if errorlevel 1 ( echo tailscale not found - skipped goto cloudflare ) tailscale funnel --bg --yes %PORT% >nul for /f "usebackq delims=" %%u in (`powershell -NoProfile -Command "try { (tailscale status --json | ConvertFrom-Json).Self.DNSName.TrimEnd('.') } catch { '' }"`) do set "TSHOST=%%u" if defined TSHOST ( echo on: https://%TSHOST%/ ) else ( echo WARNING: could not read the Tailscale name - is Tailscale logged in? ) REM ---------------------------------------------------------------- 3. Cloudflare quick tunnel :cloudflare echo [3/4] Cloudflare tunnel... where cloudflared >nul 2>&1 if errorlevel 1 ( echo cloudflared not found - skipped goto selftest ) tasklist /fi "imagename eq cloudflared.exe" 2>nul | find /i "cloudflared.exe" >nul if not errorlevel 1 ( echo already running - skipped ^(its URL is in cloudflared.log^) goto selftest ) del /f /q "%CFLOG%" 2>nul powershell -NoProfile -Command "Start-Process cloudflared -ArgumentList 'tunnel --url http://127.0.0.1:%PORT% --logfile \"%CFLOG%\"' -WindowStyle Hidden" set /a n=0 :waitcf findstr /r /c:"https://[a-zA-Z0-9-]*\.trycloudflare\.com" "%CFLOG%" >nul 2>&1 if not errorlevel 1 goto selftest set /a n+=1 if %n% geq 20 goto selftest timeout /t 1 /nobreak >nul goto waitcf REM ---------------------------------------------------------------- 4. check the URLs :selftest echo [4/4] Checking the endpoints (wg-client must download)... call :check "http://127.0.0.1:%PORT%" if defined TSHOST call :check "https://%TSHOST%" echo. echo ========================================== echo ACTIVE ENDPOINTS: echo ========================================== echo Local: http://127.0.0.1:%PORT%/ if defined TSHOST ( echo Tailscale Funnel: https://%TSHOST%/ ) else ( echo Tailscale Funnel: not available ) echo Cloudflare Tunnel: powershell -NoProfile -Command "$m = Select-String -Path '%CFLOG%' -Pattern 'https://[a-zA-Z0-9-]+\.trycloudflare\.com' -ErrorAction SilentlyContinue; if ($m) { ' ' + $m.Matches[0].Value + ' (changes every time cloudflared starts)' } else { ' not available - check cloudflared.log' }" echo LAN fallback: %LANURL%/ (trident, always on) echo ========================================== if /i not "%~1"=="/startup" pause exit /b 0 REM ---------------------------------------------------------------- /install :install set "SU=%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup\arm-server-start.cmd" > "%SU%" echo @echo off >>"%SU%" echo start "Arm server" /min cmd /c ""%~f0" /startup" echo Installed: %SU% echo start_all.bat now runs every time you log in to this PC. echo To undo: delete that file. pause exit /b 0 REM ---------------------------------------------------------------- helpers :listening REM errorlevel 0 when something is listening on %PORT% netstat -ano | findstr /r /c:":%PORT% .*LISTENING" >nul exit /b %errorlevel% :check for /f "usebackq delims=" %%r in (`powershell -NoProfile -Command "try { $r = Invoke-WebRequest -UseBasicParsing -Method Head -TimeoutSec 10 '%~1/wg-client'; 'OK ' + $r.StatusCode } catch { 'FAIL ' + $_.Exception.Message }"`) do echo %~1 -^> %%r exit /b 0