param( [ValidateSet('production', 'demo', 'check')] [string]$Mode = 'production' ) $ErrorActionPreference = 'Stop' function Import-SenseEnvironment { param([string]$Path) if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { return } $lineNumber = 0 foreach ($line in Get-Content -LiteralPath $Path -Encoding UTF8) { $lineNumber++ $trimmed = $line.Trim() if ($trimmed.Length -eq 0 -or $trimmed.StartsWith('#')) { continue } if ($line -notmatch '^\s*(SENSE_[A-Z0-9_]+)\s*=(.*)$') { throw "config\sense.env line $lineNumber must use SENSE_NAME=value format" } $name = $Matches[1] $value = $Matches[2].Trim() if ($value.Length -ge 2) { $first = $value[0] $last = $value[$value.Length - 1] if (($first -eq '"' -and $last -eq '"') -or ($first -eq "'" -and $last -eq "'")) { $value = $value.Substring(1, $value.Length - 2) } } $current = [Environment]::GetEnvironmentVariable($name, 'Process') if ([string]::IsNullOrEmpty($current)) { [Environment]::SetEnvironmentVariable($name, $value, 'Process') } } } function Assert-RequiredEnvironment { param([string[]]$Names) foreach ($name in $Names) { if ([string]::IsNullOrWhiteSpace([Environment]::GetEnvironmentVariable($name, 'Process'))) { throw "$name is required in production mode" } } } try { $runtimeRoot = Split-Path -Parent $MyInvocation.MyCommand.Path Import-SenseEnvironment -Path (Join-Path $runtimeRoot 'config\sense.env') [Environment]::SetEnvironmentVariable('SENSE_UI_STATIC_DIR', (Join-Path $runtimeRoot 'ui'), 'Process') if ([string]::IsNullOrWhiteSpace($env:SENSE_HTTP_ADDRESS)) { $env:SENSE_HTTP_ADDRESS = '127.0.0.1:18080' } if ($Mode -eq 'demo') { $env:SENSE_DATABASE_MODE = 'memory' Write-Host "Starting Sense in temporary demo mode at http://$($env:SENSE_HTTP_ADDRESS) ..." Write-Host 'Demo data is discarded when the process stops. Do not use this mode in production.' } else { $env:SENSE_DATABASE_MODE = 'postgres' Assert-RequiredEnvironment -Names @( 'SENSE_DATABASE_URL', 'SENSE_IDENTITY_SIGNING_KEY', 'SENSE_BOOTSTRAP_TOKEN', 'SENSE_CREDENTIAL_KEY' ) if ($Mode -eq 'check') { Write-Host 'Sense production configuration check passed.' exit 0 } Write-Host "Starting Sense in production mode at $($env:SENSE_HTTP_ADDRESS) ..." } $server = Join-Path $runtimeRoot 'sense-server.exe' if (-not (Test-Path -LiteralPath $server -PathType Leaf)) { throw 'sense-server.exe was not found beside the start script' } & $server exit $LASTEXITCODE } catch { Write-Host "[ERROR] $($_.Exception.Message)" Write-Host 'See README-WINDOWS.md and config\sense.env.example.' exit 1 }