mirror of
https://github.com/hansjone/netx.git
synced 2026-10-08 22:20:58 +08:00
Selecting built-in PostgreSQL now always applies setup_first_run after files copy; failed config shows a clear error instead of a misleading first-time tip. Co-authored-by: Cursor <cursoragent@cursor.com>
127 lines
5.3 KiB
PowerShell
127 lines
5.3 KiB
PowerShell
param(
|
|
[ValidateSet("tray", "start", "stop", "setup", "update")]
|
|
[string]$Action = "tray",
|
|
[string]$ProgramRoot = "",
|
|
[string]$DataRoot = "",
|
|
[switch]$StartOnLaunch = $true
|
|
)
|
|
|
|
# Visible entrypoint for Start Menu / desktop shortcuts.
|
|
# Nested PowerShell runs are hidden; only failures show a message box.
|
|
|
|
$ErrorActionPreference = "Stop"
|
|
. "$PSScriptRoot\_common.ps1"
|
|
|
|
Add-Type -AssemblyName System.Windows.Forms
|
|
|
|
$zh = ([cultureinfo]::CurrentUICulture.Name -match '^(zh|zh-)')
|
|
function T([string]$En, [string]$Zh) {
|
|
if ($zh) { return $Zh } else { return $En }
|
|
}
|
|
|
|
$prog = Get-NetxProgramRoot -Override $ProgramRoot
|
|
$data = Get-NetxDataRoot -ProgramRoot $prog -Override $DataRoot
|
|
$logDir = Join-Path $data "data\runtime"
|
|
if (-not (Test-Path $logDir)) {
|
|
New-Item -ItemType Directory -Path $logDir -Force | Out-Null
|
|
}
|
|
$log = Join-Path $logDir "launch.log"
|
|
|
|
function Write-LaunchLog([string]$Msg) {
|
|
$line = "[{0}] {1}" -f (Get-Date -Format "yyyy-MM-dd HH:mm:ss"), $Msg
|
|
Add-Content -Path $log -Value $line -Encoding utf8
|
|
}
|
|
|
|
function Show-NetxError([string]$Msg) {
|
|
Write-LaunchLog "ERROR $Msg"
|
|
[void][System.Windows.Forms.MessageBox]::Show(
|
|
$Msg,
|
|
"NetX",
|
|
[System.Windows.Forms.MessageBoxButtons]::OK,
|
|
[System.Windows.Forms.MessageBoxIcon]::Error
|
|
)
|
|
}
|
|
|
|
function Invoke-NetxHiddenPs1 {
|
|
param(
|
|
[string]$File,
|
|
[string[]]$ExtraArgs = @(),
|
|
[switch]$NoWait = $false
|
|
)
|
|
return Start-NetxPowerShell -File $File `
|
|
-Arguments (@("-ProgramRoot", $prog, "-DataRoot", $data) + $ExtraArgs) `
|
|
-WorkingDirectory $prog -WindowStyle Hidden -PassThru -Wait:(-not $NoWait)
|
|
}
|
|
|
|
function Ensure-NetxEnv {
|
|
$envPath = Join-Path $data ".env"
|
|
if (Test-Path $envPath) { return }
|
|
$cmd = Join-Path $prog "NetX-FirstRun.cmd"
|
|
throw (T `
|
|
"NetX is not configured yet (missing $envPath).`nRe-run Setup and choose built-in or external DB,`nor Start Menu → Reconfigure database:`n$cmd" `
|
|
"尚未完成数据库配置(缺少 $envPath)。`n请重新运行安装向导选择内置/外置库,`n或开始菜单 → 重新配置数据库:`n$cmd")
|
|
}
|
|
|
|
try {
|
|
Write-LaunchLog "action=$Action prog=$prog data=$data"
|
|
switch ($Action) {
|
|
"setup" {
|
|
# Visible console so user can pick bundled vs external DB.
|
|
$p = Start-NetxPowerShell -File (Join-Path $PSScriptRoot "setup_first_run.ps1") `
|
|
-Arguments @("-ProgramRoot", $prog, "-DataRoot", $data) `
|
|
-WorkingDirectory $prog -WindowStyle Normal -Wait -PassThru
|
|
if ($p.ExitCode -ne 0) { throw "setup_exit_$($p.ExitCode)" }
|
|
if (Test-Path (Join-Path $data ".env")) {
|
|
Start-NetxPowerShell -File (Join-Path $PSScriptRoot "netx_tray.ps1") `
|
|
-Arguments @("-ProgramRoot", $prog, "-DataRoot", $data, "-StartOnLaunch") `
|
|
-WorkingDirectory $prog -WindowStyle Hidden | Out-Null
|
|
}
|
|
}
|
|
"stop" {
|
|
$p = Invoke-NetxHiddenPs1 -File (Join-Path $PSScriptRoot "stop_netx_app.ps1")
|
|
if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0) { throw "stop_exit_$($p.ExitCode)" }
|
|
}
|
|
"update" {
|
|
Ensure-NetxEnv
|
|
# Update UI may need a visible window for prompts.
|
|
$p = Start-NetxPowerShell -File (Join-Path $PSScriptRoot "check_update.ps1") `
|
|
-Arguments @("-ProgramRoot", $prog, "-DataRoot", $data) `
|
|
-WorkingDirectory $prog -WindowStyle Normal -Wait -PassThru
|
|
if ($null -ne $p.ExitCode -and $p.ExitCode -ne 0 -and $p.ExitCode -ne 10) {
|
|
throw "update_exit_$($p.ExitCode)"
|
|
}
|
|
}
|
|
"start" {
|
|
Ensure-NetxEnv
|
|
$hostBind = "127.0.0.1"
|
|
$port = 8890
|
|
$envPath = Join-Path $data ".env"
|
|
if (Test-Path $envPath) {
|
|
$map = Read-DotEnv -Path $envPath
|
|
if ($map["NETX_HOST"]) { $hostBind = $map["NETX_HOST"] }
|
|
if ($map["NETX_PORT"]) { try { $port = [int]$map["NETX_PORT"] } catch {} }
|
|
}
|
|
$p = Invoke-NetxHiddenPs1 -File (Join-Path $PSScriptRoot "start_netx_app.ps1") -ExtraArgs @("-SkipBrowser")
|
|
if ($p.ExitCode -ne 0) { throw "start_exit_$($p.ExitCode)" }
|
|
if (Wait-NetxApiHealthy -HostName $hostBind -Port $port -TimeoutSec 180) {
|
|
try { Start-Process "http://${hostBind}:${port}/" } catch {}
|
|
} else {
|
|
throw (T `
|
|
"NetX started but /health not ready within 180s.`nSee: $logDir\netx.err.log" `
|
|
"NetX 已启动但 /health 在 180 秒内未就绪。`n请查看: $logDir\netx.err.log")
|
|
}
|
|
}
|
|
"tray" {
|
|
Ensure-NetxEnv
|
|
$extra = @("-ProgramRoot", $prog, "-DataRoot", $data)
|
|
if ($StartOnLaunch) { $extra += "-StartOnLaunch" }
|
|
# Detach tray; do not leave a success MessageBox (keeps a console open).
|
|
Start-NetxPowerShell -File (Join-Path $PSScriptRoot "netx_tray.ps1") `
|
|
-Arguments $extra -WorkingDirectory $prog -WindowStyle Hidden | Out-Null
|
|
}
|
|
}
|
|
Write-LaunchLog "action=$Action ok"
|
|
} catch {
|
|
Show-NetxError ((T "NetX failed to start:`n$($_.Exception.Message)" "NetX 启动失败:`n$($_.Exception.Message)") + "`n`n$log")
|
|
exit 1
|
|
}
|