param( [switch]$NoBrowser, [switch]$NoPause ) $ErrorActionPreference = "Stop" function Test-IsAdmin { $currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } if (-not (Test-IsAdmin)) { $childArgs = @( "-NoProfile", "-ExecutionPolicy", "Bypass", "-File", "`"$PSCommandPath`"" ) if ($NoBrowser) { $childArgs += "-NoBrowser" } if ($NoPause) { $childArgs += "-NoPause" } Start-Process -FilePath "powershell.exe" -Verb RunAs -ArgumentList @( $childArgs ) exit 0 } $projectDir = "/home/hyein/project" $apiPort = 4000 $localUrl = "http://localhost:$apiPort/PTC-lab-manage/" $preferredLanIp = "172.16.40.36" $defaultSource = "/home/hyein/project/PTC(2023-2026.02).xlsx" $sourceConfigPath = "/home/hyein/project/server/ptc_source_path.txt" function Invoke-WslBash([string]$command) { $output = & wsl.exe bash -lc $command 2>&1 $exitCode = $LASTEXITCODE return [PSCustomObject]@{ Output = @($output) ExitCode = $exitCode } } $currentSourceResult = Invoke-WslBash "cat '$sourceConfigPath' 2>/dev/null || printf '%s\n' '$defaultSource'" $currentSource = ($currentSourceResult.Output | Select-Object -First 1).Trim() if ([string]::IsNullOrWhiteSpace($currentSource)) { $currentSource = $defaultSource } Write-Host "Starting PTC server..." Write-Host "Source file: $currentSource" $startResult = Invoke-WslBash "pkill -f '/home/hyein/project/server/ptc_api_server.py' >/dev/null 2>&1 || true; nohup python3 /home/hyein/project/server/ptc_api_server.py >/tmp/ptc_api.log 2>&1 & sleep 3" if ($startResult.ExitCode -ne 0) { Write-Host "Failed to start the server in WSL." -ForegroundColor Red if (-not $NoPause) { Read-Host "Press Enter to exit" } exit 1 } $healthResult = Invoke-WslBash "curl -fsS http://127.0.0.1:$apiPort/api/health >/tmp/ptc_api_health.json && curl -fsSI http://127.0.0.1:$apiPort/PTC-lab/ >/tmp/ptc_web_health.txt && curl -fsSI http://127.0.0.1:$apiPort/PTC-lab-manage/ >/tmp/ptc_manage_web_health.txt" if ($healthResult.ExitCode -ne 0) { Write-Host "Local server check failed. Recent server log:" -ForegroundColor Red $logResult = Invoke-WslBash "tail -n 80 /tmp/ptc_api.log" $logResult.Output | ForEach-Object { Write-Host $_ } if (-not $NoPause) { Read-Host "Press Enter to exit" } exit 1 } if (-not $NoBrowser) { Start-Process $localUrl } Write-Host "" Write-Host "Local URL: $localUrl" $lanIps = @(Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '127.*' -and $_.IPAddress -notlike '169.254.*' -and $_.PrefixOrigin -ne 'WellKnown' } | Sort-Object InterfaceMetric, SkipAsSource | Select-Object -ExpandProperty IPAddress) $lanIp = $lanIps | Select-Object -First 1 $wslIpResult = Invoke-WslBash "hostname -I | awk '{print \$1}'" $wslIp = ($wslIpResult.Output | Select-Object -First 1).Trim() if (-not [string]::IsNullOrWhiteSpace($lanIp) -and -not [string]::IsNullOrWhiteSpace($wslIp)) { Write-Host "Configuring LAN sharing..." & netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=$apiPort | Out-Null & netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=$apiPort connectaddress=$wslIp connectport=$apiPort | Out-Null & netsh advfirewall firewall delete rule name="PTC 4000" | Out-Null & netsh advfirewall firewall add rule name="PTC 4000" dir=in action=allow protocol=TCP localport=$apiPort | Out-Null if (-not ($lanIps -contains $preferredLanIp)) { Write-Host "Preferred share IP $preferredLanIp is not assigned on this PC." -ForegroundColor Red Write-Host "Detected Windows IPs: $($lanIps -join ', ')" -ForegroundColor Yellow if (-not $NoPause) { Read-Host "Press Enter to exit" } exit 1 } $shareIp = $preferredLanIp $shareUrl = "http://$shareIp:$apiPort/PTC-lab-manage/" Write-Host "Windows IP: $lanIp" Write-Host "Preferred share IP in use: $shareIp" Write-Host "WSL IP: $wslIp" Write-Host "LAN URL: $shareUrl" Set-Clipboard -Value $shareUrl Write-Host "The share URL has been copied to the clipboard." try { $lanWebStatus = (Invoke-WebRequest -Uri $shareUrl -UseBasicParsing -TimeoutSec 5).StatusCode $lanApiStatus = (Invoke-WebRequest -Uri "http://$shareIp:$apiPort/api/health" -UseBasicParsing -TimeoutSec 5).StatusCode Write-Host "LAN web check: $lanWebStatus" Write-Host "LAN api check: $lanApiStatus" } catch { Write-Host "LAN check failed for $shareIp:$apiPort" -ForegroundColor Red Write-Host $_.Exception.Message -ForegroundColor Yellow } } else { Write-Host "LAN sharing was skipped because Windows IP or WSL IP could not be detected." } if (-not $NoPause) { Read-Host "Press Enter to close" }