[CmdletBinding()] param( [switch]$ValidateOnly ) $ErrorActionPreference = "Stop" $ProjectRoot = (Resolve-Path (Join-Path $PSScriptRoot "..")).Path $FrozenExecutable = Join-Path $ProjectRoot "dist\DoctorWorkstation\DoctorWorkstation.exe" $ProjectPython = Join-Path $ProjectRoot ".venv\Scripts\python.exe" $ProjectUvCache = Join-Path $ProjectRoot ".uv-cache" $SourceRoot = Join-Path $ProjectRoot "src" function Test-ProjectPython { param([Parameter(Mandatory = $true)][string]$Candidate) if (-not (Test-Path -LiteralPath $Candidate -PathType Leaf)) { return $false } try { & $Candidate -c "import sys, httpx, PySide6; raise SystemExit(0 if sys.version_info >= (3, 11) else 1)" 2>$null return $LASTEXITCODE -eq 0 } catch { return $false } } function Find-Uv { $Command = Get-Command uv -CommandType Application -ErrorAction SilentlyContinue | Select-Object -First 1 if ($Command) { return $Command.Source } return $null } try { if (Test-Path -LiteralPath $FrozenExecutable -PathType Leaf) { Write-Host "Using packaged application: $FrozenExecutable" if ($ValidateOnly) { Write-Host "Windows run entry validation passed." exit 0 } & $FrozenExecutable $ApplicationExitCode = $LASTEXITCODE if ($null -eq $ApplicationExitCode) { $ApplicationExitCode = 0 } if ($ApplicationExitCode -ne 0) { Write-Host "DoctorWorkstation exited with code $ApplicationExitCode" -ForegroundColor Red } exit $ApplicationExitCode } $Python = $null if (Test-ProjectPython -Candidate $ProjectPython) { $Python = $ProjectPython Write-Host "Using existing project environment: $ProjectPython" } else { $Uv = Find-Uv if (-not $Uv) { throw "No packaged application or usable .venv was found, and uv is not installed." } if ($ValidateOnly) { Write-Host "Source fallback is available through uv: $Uv" Write-Host "Windows run entry validation passed." exit 0 } Write-Host "Preparing the project environment with uv..." $PreviousProjectEnvironment = [Environment]::GetEnvironmentVariable( "UV_PROJECT_ENVIRONMENT", "Process" ) $PreviousUvCache = [Environment]::GetEnvironmentVariable( "UV_CACHE_DIR", "Process" ) New-Item -ItemType Directory -Path $ProjectUvCache -Force | Out-Null [Environment]::SetEnvironmentVariable( "UV_PROJECT_ENVIRONMENT", (Join-Path $ProjectRoot ".venv"), "Process" ) [Environment]::SetEnvironmentVariable( "UV_CACHE_DIR", $ProjectUvCache, "Process" ) Push-Location $ProjectRoot try { & $Uv sync --frozen if ($LASTEXITCODE -ne 0) { throw "uv sync failed with exit code $LASTEXITCODE" } } finally { Pop-Location [Environment]::SetEnvironmentVariable( "UV_PROJECT_ENVIRONMENT", $PreviousProjectEnvironment, "Process" ) [Environment]::SetEnvironmentVariable( "UV_CACHE_DIR", $PreviousUvCache, "Process" ) } if (-not (Test-ProjectPython -Candidate $ProjectPython)) { throw "uv completed, but the project Python is still unusable: $ProjectPython" } $Python = $ProjectPython } if ($ValidateOnly) { Write-Host "Windows run entry validation passed." exit 0 } $PreviousPythonPath = [Environment]::GetEnvironmentVariable("PYTHONPATH", "Process") $env:PYTHONPATH = if ($PreviousPythonPath) { $SourceRoot + [System.IO.Path]::PathSeparator + $PreviousPythonPath } else { $SourceRoot } Push-Location $ProjectRoot try { & $Python -m doctor_workstation $ApplicationExitCode = $LASTEXITCODE } finally { Pop-Location [Environment]::SetEnvironmentVariable("PYTHONPATH", $PreviousPythonPath, "Process") } if ($null -eq $ApplicationExitCode) { $ApplicationExitCode = 0 } if ($ApplicationExitCode -ne 0) { Write-Host "DoctorWorkstation exited with code $ApplicationExitCode" -ForegroundColor Red } exit $ApplicationExitCode } catch { $FailureExitCode = if ($LASTEXITCODE -is [int] -and $LASTEXITCODE -ne 0) { $LASTEXITCODE } else { 1 } Write-Host "Unable to start DoctorWorkstation." -ForegroundColor Red Write-Host $_.Exception.Message -ForegroundColor Red exit $FailureExitCode }