@echo off :: ============================================================================= :: TeslaLauncher Modern — Installation Script :: ============================================================================= :: Run as Administrator on each cockpit PC. :: Must be run from the TeslaLauncher\ folder produced by build.bat: :: :: TeslaLauncher\ :: install.bat <- this file :: Service\TeslaLauncherService.exe :: Agent\TeslaLauncherAgent.exe :: dx9201006\DXSETUP.exe (DirectX June 2010 redist) :: openal\oalinst.exe (OpenAL redist) :: UltraVNC\UltraVNC_x64_Setup.exe (UltraVNC server + UltraVNC.inf) :: ============================================================================= setlocal enabledelayedexpansion echo ============================================================ echo Tesla Launcher v4.11.4.1 - Installation echo ============================================================ echo. :: ── Paths ───────────────────────────────────────────────────────────────────── set ROOT=%~dp0 set SERVICE_SRC=%ROOT%Service set AGENT_SRC=%ROOT%Agent set INSTALL_DIR=C:\Program Files\TeslaLauncher set DATA_DIR=C:\ProgramData\TeslaLauncher set SERVICE_EXE=%INSTALL_DIR%\TeslaLauncherService.exe set AGENT_EXE=%INSTALL_DIR%\TeslaLauncherAgent.exe set SERVICE_NAME=Tesla Application Launcher set SERVICE_DISPLAY=Tesla Application Launcher set CONSOLE_PORT=53290 :: Auto-login account for the cockpit (kiosk). Plain-text password in the :: registry is by design here — closed network, single-purpose PC. set AUTOLOGIN_USER=Firestorm set AUTOLOGIN_PASS=thor6 :: Workgroup every pod on this site joins. Keep it the same across all pods so :: the mw4files / c shares browse cleanly. Change once per site if needed. set WORKGROUP=Tesla :: ── Admin check ─────────────────────────────────────────────────────────────── net session >nul 2>&1 if %errorlevel% neq 0 ( echo ERROR: This script must be run as Administrator. pause & exit /b 1 ) :: ── Verify source files ─────────────────────────────────────────────────────── if not exist "%SERVICE_SRC%\TeslaLauncherService.exe" ( echo ERROR: TeslaLauncherService.exe not found in %SERVICE_SRC% echo Run build.bat first, then run install.bat from the TeslaLauncher\ folder. pause & exit /b 1 ) if not exist "%AGENT_SRC%\TeslaLauncherAgent.exe" ( echo ERROR: TeslaLauncherAgent.exe not found in %AGENT_SRC% echo Run build.bat first, then run install.bat from the TeslaLauncher\ folder. pause & exit /b 1 ) :: ── Detect and clean up existing installation ───────────────────────────────── set EXISTING=0 if exist "%SERVICE_EXE%" set EXISTING=1 if exist "%AGENT_EXE%" set EXISTING=1 if "%EXISTING%"=="1" ( echo Existing installation detected. Cleaning up... echo. :: Stop and kill the Agent process taskkill /F /IM TeslaLauncherAgent.exe >nul 2>&1 echo Agent process stopped. :: Stop and remove the service, wait for it to fully stop sc stop "%SERVICE_NAME%" >nul 2>&1 sc stop "Tesla Application Launcher" >nul 2>&1 timeout /t 3 /nobreak >nul sc delete "%SERVICE_NAME%" >nul 2>&1 sc delete "Tesla Application Launcher" >nul 2>&1 timeout /t 2 /nobreak >nul echo Service stopped and removed. :: Delete old executables, logs, and session key so SecureConfig re-runs del /F /Q "%SERVICE_EXE%" >nul 2>&1 del /F /Q "%AGENT_EXE%" >nul 2>&1 del /F /Q "%INSTALL_DIR%\podconf.log" >nul 2>&1 del /F /Q "%DATA_DIR%\TeslaKeyStore.key" >nul 2>&1 del /F /Q "%DATA_DIR%\LaunchApps.xml" >nul 2>&1 del /F /Q "%DATA_DIR%\configuring.json" >nul 2>&1 echo Old executables, logs, session key, and app config deleted. :: Reset all physical Ethernet adapters to DHCP so the SecureConfig :: protocol triggers correctly on the next boot. :: We must REMOVE the static IP address entry first, then enable DHCP. :: Set-NetIPInterface -Dhcp Enabled alone only flips the DHCP flag but :: leaves the static address in the registry, so IsMachineConfigured() :: still sees a non-DHCP adapter on the next boot and skips SecureConfig. echo Resetting network adapters to DHCP... powershell -NoProfile -Command "Get-NetAdapter -Physical | Where-Object {$_.Status -eq 'Up'} | ForEach-Object { $n=$_.Name; Get-NetIPAddress -InterfaceAlias $n -AddressFamily IPv4 -EA 0 | Where-Object {$_.PrefixOrigin -ne 'WellKnown' -and $_.PrefixOrigin -ne 'Dhcp'} | Remove-NetIPAddress -Confirm:$false -EA 0; Set-NetIPInterface -InterfaceAlias $n -Dhcp Enabled -EA 0 }; Get-NetAdapter -Physical | Where-Object {$_.Status -eq 'Up'} | Set-DnsClientServerAddress -ResetServerAddresses" >nul 2>&1 echo Network adapters reset to DHCP. echo. ) else ( :: No existing install — still remove any stale service registration sc stop "%SERVICE_NAME%" >nul 2>&1 sc stop "Tesla Application Launcher" >nul 2>&1 sc delete "%SERVICE_NAME%" >nul 2>&1 sc delete "Tesla Application Launcher" >nul 2>&1 timeout /t 2 /nobreak >nul ) :: ── STEP 1: Create directories ──────────────────────────────────────────────── echo [1/8] Creating directories... if not exist "%INSTALL_DIR%" mkdir "%INSTALL_DIR%" if not exist "%DATA_DIR%" mkdir "%DATA_DIR%" if not exist "C:\Games" mkdir "C:\Games" :: Grant all users modify access to the data and games directories so :: the Service and Agent can write files (LaunchApps.xml, game installs). icacls "%DATA_DIR%" /grant *S-1-5-32-545:(OI)(CI)M /T >nul 2>&1 icacls "C:\Games" /grant *S-1-5-32-545:(OI)(CI)M /T >nul 2>&1 echo %INSTALL_DIR% echo %DATA_DIR% (Users: modify access) echo C:\Games (Users: modify access) :: ── STEP 2: Copy files ──────────────────────────────────────────────────────── echo [2/8] Copying files... :: net48 framework-dependent build: each folder holds the exe + its dependency :: DLLs + .config. Copy both folders into the install dir (shared DLLs overwrite :: identically; the two .exe.config files coexist). copy /Y "%SERVICE_SRC%\*.*" "%INSTALL_DIR%\" >nul copy /Y "%AGENT_SRC%\*.*" "%INSTALL_DIR%\" >nul :: Install DirectX June 2010 runtime (required by games) if exist "%ROOT%\dx9201006\DXSETUP.exe" ( echo Installing DirectX runtime... "%ROOT%\dx9201006\DXSETUP.exe" /silent echo DirectX installed. ) :: Install OpenAL runtime (required by game audio) if exist "%ROOT%\openal\oalinst.exe" ( echo Installing OpenAL runtime... "%ROOT%\openal\oalinst.exe" /s echo OpenAL installed. ) :: Install UltraVNC server (remote diagnostics). The Inno installer lays down :: the files and (via /loadinf) sets the install dir + VNC password; we then :: register and start the service EXPLICITLY with winvnc.exe. Doing the service :: step ourselves means a missing/incomplete "install service" task in the :: answer file can't leave the pod with the files present but nothing listening. set UVNC_SETUP=%ROOT%UltraVNC\UltraVNC_x64_Setup.exe set UVNC_DIR=C:\Program Files\uvnc bvba\UltraVNC if exist "%UVNC_SETUP%" ( echo Installing UltraVNC server... start "" /wait "%UVNC_SETUP%" /verysilent /norestart /loadinf="%ROOT%UltraVNC\UltraVNC.inf" ) :: Enable SMB1 client AND server (required by game networking). The pod both :: reaches SMB1 shares (client) and hosts the mw4files / c shares below (server), :: and Win10/11 ship both SMB1 sub-features off by default — so enable all three :: (umbrella + client + server); each child pulls in the umbrella via /All. echo Enabling SMB1 file sharing (client + server)... dism /Online /Enable-Feature /FeatureName:SMB1Protocol /All /NoRestart >nul 2>&1 dism /Online /Enable-Feature /FeatureName:SMB1Protocol-Client /All /NoRestart >nul 2>&1 dism /Online /Enable-Feature /FeatureName:SMB1Protocol-Server /All /NoRestart >nul 2>&1 echo SMB1 client + server enabled (reboot required to take effect). :: Create and share game-data folders (closed network — open to Everyone). echo Creating network shares... if not exist "C:\mw4files" mkdir "C:\mw4files" :: Grant Everyone modify on the NTFS side so the share grant is effective. icacls "C:\mw4files" /grant *S-1-1-0:(OI)(CI)M /T >nul 2>&1 :: Recreate shares idempotently (net share fails if the name already exists). net share mw4files /delete >nul 2>&1 net share mw4files=C:\mw4files /grant:Everyone,FULL >nul 2>&1 echo "Share \\%COMPUTERNAME%\mw4files -> C:\mw4files (Everyone: Full)" net share c /delete >nul 2>&1 net share c=C:\ /grant:Everyone,FULL >nul 2>&1 echo "Share \\%COMPUTERNAME%\c -> C:\ (Everyone: Full)" :: Join the site workgroup so every pod shares one browse list. Add-Computer :: throws if the machine is already in that workgroup, so the error is ignored. :: Takes effect on the reboot at the end of this script (same as the hostname :: SecureConfig applies on first boot). echo Joining workgroup "%WORKGROUP%"... powershell -NoProfile -Command "try { Add-Computer -WorkgroupName '%WORKGROUP%' -Force -ErrorAction Stop } catch { }" >nul 2>&1 echo Workgroup set to "%WORKGROUP%" (effective after reboot). :: Enable DirectPlay (required by older games) echo Enabling DirectPlay... dism /Online /Enable-Feature /FeatureName:DirectPlay /All /NoRestart >nul 2>&1 echo DirectPlay enabled. echo Done. :: ── STEP 3: Install Windows Service ────────────────────────────────────────── echo [3/8] Installing Windows Service... sc create "%SERVICE_NAME%" ^ binPath= "\"%SERVICE_EXE%\"" ^ DisplayName= "%SERVICE_DISPLAY%" ^ start= delayed-auto ^ obj= LocalSystem ^ type= own if %errorlevel% neq 0 ( echo ERROR: Failed to register Windows Service. pause & exit /b 1 ) sc description "%SERVICE_NAME%" ^ "Tesla Application Launcher - accepts TeslaConsole connections and controls simulation software" sc failure "%SERVICE_NAME%" ^ reset= 86400 actions= restart/5000/restart/10000/restart/30000 :: Delay auto-start by 20 seconds to let the network stack settle reg add "HKLM\SYSTEM\CurrentControlSet\Services\Tesla Application Launcher" ^ /v AutoStartDelay /t REG_DWORD /d 20000 /f >nul :: Set the global delayed-auto-start delay to 20 seconds (default is 120s) reg add "HKLM\SYSTEM\CurrentControlSet\Control" ^ /v AutoStartDelay /t REG_DWORD /d 20000 /f >nul echo Service registered: "%SERVICE_NAME%" (20s per-service delay, 20s global delay) :: ── STEP 4: Disable Windows Firewall (closed network) ──────────────────────── echo. echo [4/8] Disabling Windows Firewall (closed network)... :: Disable firewall on all profiles — pods run on a closed network netsh advfirewall set allprofiles state off echo Windows Firewall disabled on all profiles. :: ── STEP 5: Power settings (max performance, no sleep) ────────────────────── echo. echo [5/8] Configuring power settings... :: Activate Ultimate Performance plan (hidden by default, GUID is well-known) powercfg -duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61 >nul 2>&1 for /f "tokens=4" %%g in ('powercfg -list ^| findstr /i "Ultimate"') do ( powercfg -setactive %%g ) echo Ultimate Performance power plan activated. :: Disable all sleep/hibernate/standby timeouts (AC power) powercfg -change -standby-timeout-ac 0 powercfg -change -hibernate-timeout-ac 0 powercfg -change -monitor-timeout-ac 0 powercfg -change -disk-timeout-ac 0 powercfg -h off >nul 2>&1 echo Sleep, hibernate, monitor timeout, and disk timeout disabled. :: ── STEP 6: Disable notifications ─────────────────────────────────────────── echo. echo [6/8] Disabling notifications... :: These are machine-wide Group Policy keys (HKLM) so they apply to EVERY user, :: including the auto-login kiosk account. Per-user HKCU tweaks would only touch :: the admin running this installer, not the account the pod actually runs as. :: Remove Action Center / Notification Center entirely reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\Explorer" ^ /v DisableNotificationCenter /t REG_DWORD /d 1 /f >nul :: Kill all toast/app notifications (desktop and lock screen) and cloud toasts reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ^ /v NoToastApplicationNotification /t REG_DWORD /d 1 /f >nul reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ^ /v NoToastApplicationNotificationOnLockScreen /t REG_DWORD /d 1 /f >nul reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CurrentVersion\PushNotifications" ^ /v NoCloudApplicationNotification /t REG_DWORD /d 1 /f >nul :: Suppress tips, suggestions, Spotlight, and other consumer content pop-ups reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ^ /v DisableSoftLanding /t REG_DWORD /d 1 /f >nul reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ^ /v DisableWindowsSpotlightFeatures /t REG_DWORD /d 1 /f >nul reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\CloudContent" ^ /v DisableWindowsConsumerFeatures /t REG_DWORD /d 1 /f >nul :: Silence Security & Maintenance (formerly Action Center) health notifications reg add "HKLM\SOFTWARE\Microsoft\Windows Defender Security Center\Notifications" ^ /v DisableNotifications /t REG_DWORD /d 1 /f >nul echo All Windows notifications disabled (machine-wide). :: ── STEP 7: Disable UAC ───────────────────────────────────────────────────── echo. echo [7/8] Disabling UAC... reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ^ /v EnableLUA /t REG_DWORD /d 0 /f >nul reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ^ /v ConsentPromptBehaviorAdmin /t REG_DWORD /d 0 /f >nul reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" ^ /v PromptOnSecureDesktop /t REG_DWORD /d 0 /f >nul echo UAC disabled (takes effect after reboot). :: ── STEP 8: Configure Agent auto-start and auto-login ──────────────────────── echo. echo [8/8] Configuring Agent auto-start and auto-login... set AUTORUN_KEY=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run reg add "%AUTORUN_KEY%" /v "TeslaLauncherAgent" /t REG_SZ ^ /d "\"%AGENT_EXE%\"" /f >nul echo Added TeslaLauncherAgent to HKLM\...\Run. :: Auto-login: Winlogon reads these on every boot. AutoAdminLogon=1 tells :: Winlogon to sign the DefaultUserName in with DefaultPassword without a :: prompt. DefaultDomainName="." means the local machine account. set WINLOGON=HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon reg add "%WINLOGON%" /v AutoAdminLogon /t REG_SZ /d "1" /f >nul reg add "%WINLOGON%" /v DefaultUserName /t REG_SZ /d "%AUTOLOGIN_USER%" /f >nul reg add "%WINLOGON%" /v DefaultPassword /t REG_SZ /d "%AUTOLOGIN_PASS%" /f >nul reg add "%WINLOGON%" /v DefaultDomainName /t REG_SZ /d "." /f >nul :: Re-arm auto-login after every sign-out (kiosk should never sit at a prompt). reg add "%WINLOGON%" /v ForceAutoLogon /t REG_SZ /d "1" /f >nul :: Clear any logon-count cap that would disable auto-login after N boots. reg delete "%WINLOGON%" /v AutoLogonCount /f >nul 2>&1 :: Some builds require this flag off for a plain-text auto-login password to :: be honored (device-passwordless / Windows Hello preference). reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\PasswordLess\Device" ^ /v DevicePasswordLessBuildVersion /t REG_DWORD /d 0 /f >nul 2>&1 echo Auto-login configured for user "%AUTOLOGIN_USER%". :: ── Done ────────────────────────────────────────────────────────────────────── echo. echo ============================================================ echo Installation Complete! echo ============================================================ echo. echo Installed to : %INSTALL_DIR% echo Config dir : %DATA_DIR% echo Firewall : disabled (closed network) echo. echo Rebooting in 10 seconds... echo The Service and Agent will start automatically in the correct order. echo On first boot with DHCP, SecureConfig runs automatically — echo watch plasma or on main screen for the Request ID and Passphrase. echo. echo After reboot: use Console to install apps. echo. shutdown /r /t 10