daShangDao_psiWebApp/verifyTool/kfzgs-launcher.ps1
97694731 520712bfab
Some checks failed
CI / build (18.x) (push) Failing after 31m9s
CI / build (20.x) (push) Failing after 1m34s
CI / deploy-preview (push) Has been skipped
CI / lint (push) Failing after 1m35s
CI / test (push) Failing after 33s
CI / security (push) Failing after 34s
程序所在位置
2026-06-26 16:51:51 +08:00

189 lines
7.3 KiB
PowerShell

# kfzgs-launcher.ps1 - 核价器启动脚本 (便携版)
# 用法:
# 协议模式: powershell -File kfzgs-launcher.ps1 -url "kfzgs://launch?dir=..."
# 服务模式: powershell -File kfzgs-launcher.ps1
param([string]$url = "")
$SERVICE_ID = "kfz-goods-pricing"
$HTTP_PORT = 5000
$SCRIPT_DIR = Split-Path $MyInvocation.MyCommand.Path -Parent
# 从同目录下的 config.json 读取 exe 路径,没有则用同目录下默认 exe
$CONFIG_FILE = Join-Path $SCRIPT_DIR "launcher-config.json"
$DEFAULT_EXE = Join-Path $SCRIPT_DIR "kfz-goods-pricing.exe"
function Load-Config {
if (Test-Path $CONFIG_FILE) {
try {
$config = Get-Content $CONFIG_FILE -Raw | ConvertFrom-Json
if ($config.exe_path) { return $config.exe_path }
} catch {}
}
return $DEFAULT_EXE
}
function Save-Config($exePath) {
@{ exe_path = $exePath; id = $SERVICE_ID; name = "核价器" } | ConvertTo-Json | Out-File $CONFIG_FILE -Encoding UTF8
}
$EXE_PATH = Load-Config
function Parse-KfzgsUrl($rawUrl) {
$decoded = [System.Uri]::UnescapeDataString($rawUrl)
$stripped = $decoded -replace "^kfzgs://", ""
$action = ""
$params = @{}
if ($stripped -match "^([^?]+)\?(.*)$") {
$action = $Matches[1]
$query = $Matches[2]
$query -split "&" | ForEach-Object {
$parts = $_ -split "=", 2
if ($parts.Count -eq 2) { $params[$parts[0]] = $parts[1] }
}
} elseif ($stripped -notmatch "[?]") {
$action = $stripped
}
return @{ action = $action; params = $params }
}
function Invoke-ProtocolHandler($rawUrl) {
$parsed = Parse-KfzgsUrl $rawUrl
$p = $parsed.params
if ($parsed.action -eq "launch") {
$dir = $p["dir"] -replace "/", "\"
$exeName = $p["exe"]
if ($exeName) {
if ($dir) {
if ($dir.EndsWith("\")) { $fullPath = "$dir$exeName" }
else { $fullPath = "$dir\$exeName" }
} else {
$fullPath = Join-Path $SCRIPT_DIR $exeName
}
} elseif ($dir -and $dir -match "\.exe$") {
if (Test-Path $dir) { $fullPath = $dir }
else { $fullPath = Join-Path $SCRIPT_DIR $dir }
} else { $fullPath = $EXE_PATH }
if ($fullPath -ne $EXE_PATH) {
Save-Config $fullPath
$script:EXE_PATH = $fullPath
}
if (Test-Path $fullPath) {
$parentDir = Split-Path $fullPath -Parent
Start-Process -FilePath $fullPath -WorkingDirectory $parentDir -WindowStyle Normal
}
}
}
function Start-ApiServer {
$listener = New-Object System.Net.HttpListener
$listener.Prefixes.Add("http://127.0.0.1:$HTTP_PORT/")
try { $listener.Start() } catch { exit 1 }
$services = @{}
$services[$SERVICE_ID] = @{
id = $SERVICE_ID
name = "核价器"
exe_path = $EXE_PATH
running = $false
}
while ($listener.IsListening) {
$context = $listener.GetContext()
$request = $context.Request
$response = $context.Response
if ($request.HttpMethod -eq "OPTIONS") {
$response.AddHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
$response.AddHeader("Access-Control-Allow-Headers", "Content-Type")
$response.StatusCode = 204
$response.Close()
continue
}
$path = $request.Url.AbsolutePath
$result = @{ code = 0; msg = "ok" }
try {
if ($path -eq "/api/services") {
if ($request.HttpMethod -eq "GET") {
$services[$SERVICE_ID]["exe_path"] = $EXE_PATH
$result["data"] = @($services.Values)
} elseif ($request.HttpMethod -eq "POST") {
$reader = New-Object System.IO.StreamReader($request.InputStream)
$body = $reader.ReadToEnd() | ConvertFrom-Json
if ($body.id -and $body.exe_path) {
$services[$body.id] = @{
id = $body.id
name = if ($body.name) { $body.name } else { $body.id }
exe_path = $body.exe_path
running = $false
}
Save-Config $body.exe_path
$script:EXE_PATH = $body.exe_path
$result["msg"] = "已注册: $($body.id)"
$result["data"] = $services[$body.id]
} else {
$result["code"] = 1
$result["msg"] = "缺少 id 或 exe_path"
}
}
}
elseif ($path -match "^/api/services/([^/]+)$" -and $request.HttpMethod -eq "GET") {
$sid = $Matches[1]
if ($services.ContainsKey($sid)) {
$result["data"] = $services[$sid]
} else {
$result["code"] = 1; $result["msg"] = "未找到"
}
}
elseif ($path -match "^/api/services/([^/]+)/start$" -and $request.HttpMethod -eq "POST") {
$sid = $Matches[1]
if ($services.ContainsKey($sid)) {
$svc = $services[$sid]
$exePath = if ($svc["exe_path"] -and (Test-Path $svc["exe_path"])) { $svc["exe_path"] } else { $EXE_PATH }
if (Test-Path $exePath) {
$parentDir = Split-Path $exePath -Parent
$proc = Start-Process -FilePath $exePath -WorkingDirectory $parentDir -WindowStyle Normal -PassThru
$svc["running"] = $true
$result["msg"] = "已启动"
$result["pid"] = $proc.Id
} else { $result["code"] = 1; $result["msg"] = "文件不存在: $exePath" }
} else { $result["code"] = 1; $result["msg"] = "未找到" }
}
elseif ($path -match "^/api/services/([^/]+)/stop$" -and $request.HttpMethod -eq "POST") {
$sid = $Matches[1]
if ($services.ContainsKey($sid)) {
$killed = $false
Get-CimInstance Win32_Process | Where-Object { $_.ExecutablePath -eq $services[$sid]["exe_path"] } | ForEach-Object {
Stop-Process -Id $_.ProcessId -Force -ErrorAction SilentlyContinue
$killed = $true
}
$services[$sid]["running"] = $false
$result["msg"] = if ($killed) { "已停止" } else { "未在运行" }
$result["killed"] = $killed
} else { $result["code"] = 1; $result["msg"] = "未找到" }
}
else { $result["code"] = 404; $result["msg"] = "未知接口" }
} catch {
$result["code"] = 1; $result["msg"] = $_.Exception.Message
}
$json = $result | ConvertTo-Json -Compress -Depth 3
$buffer = [System.Text.Encoding]::UTF8.GetBytes($json)
$response.AddHeader("Access-Control-Allow-Origin", "*")
$response.ContentType = "application/json; charset=utf-8"
$response.ContentLength64 = $buffer.Length
$response.OutputStream.Write($buffer, 0, $buffer.Length)
$response.Close()
}
}
if ($url -and $url -match "^kfzgs://") {
Invoke-ProtocolHandler $url
} else {
Start-ApiServer
}