From 80207239854a3b87bd08e8a8422c896f1b77a004 Mon Sep 17 00:00:00 2001 From: coolxll Date: Wed, 25 Mar 2026 22:32:22 +0800 Subject: [PATCH] chore: add Windows build and service scripts --- README.md | 92 +++++++++++++++++++++++++++ scripts/build.ps1 | 31 +++++++++ scripts/install-nssm-service.ps1 | 32 ++++++++++ scripts/install-winsw-service.ps1 | 59 +++++++++++++++++ scripts/lingma-ipc-proxy.xml.template | 15 +++++ 5 files changed, 229 insertions(+) create mode 100644 scripts/build.ps1 create mode 100644 scripts/install-nssm-service.ps1 create mode 100644 scripts/install-winsw-service.ps1 create mode 100644 scripts/lingma-ipc-proxy.xml.template diff --git a/README.md b/README.md index c54c532..904d3f0 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,98 @@ cd C:\Workspace\Personal\lingma-ipc-proxy go run .\cmd\lingma-ipc-proxy ``` +## Build + +Build a Windows executable: + +```powershell +cd C:\Workspace\Personal\lingma-ipc-proxy +.\scripts\build.ps1 +``` + +Default output: + +```text +dist\lingma-ipc-proxy.exe +``` + +Direct Go build command: + +```powershell +$env:CGO_ENABLED = "0" +$env:GOOS = "windows" +$env:GOARCH = "amd64" +go build -trimpath -ldflags "-s -w" -o .\dist\lingma-ipc-proxy.exe .\cmd\lingma-ipc-proxy +``` + +Run the built binary: + +```powershell +.\dist\lingma-ipc-proxy.exe --host 127.0.0.1 --port 8095 --session-mode auto +``` + +## Windows Service + +For this project, the correct deployment shape is a native Windows process, not Docker. The proxy talks to Lingma over Windows named pipes, so it should run on the same Windows host as Lingma itself. + +### NSSM + +Build first: + +```powershell +.\scripts\build.ps1 +``` + +Install with NSSM: + +```powershell +.\scripts\install-nssm-service.ps1 -NssmPath C:\Tools\nssm\nssm.exe +``` + +This wraps: + +```powershell +nssm.exe install LingmaIpcProxy C:\Workspace\Personal\lingma-ipc-proxy\dist\lingma-ipc-proxy.exe --host 127.0.0.1 --port 8095 --session-mode auto +nssm.exe set LingmaIpcProxy AppDirectory C:\Workspace\Personal\lingma-ipc-proxy +nssm.exe start LingmaIpcProxy +``` + +### WinSW + +Prepare the executable: + +```powershell +.\scripts\build.ps1 +``` + +Put a WinSW binary at: + +```text +dist\WinSW-x64.exe +``` + +Then generate the wrapper files: + +```powershell +.\scripts\install-winsw-service.ps1 +``` + +That script creates: + +- `LingmaIpcProxy.exe` +- `LingmaIpcProxy.xml` + +Then install/start: + +```powershell +.\LingmaIpcProxy.exe install +.\LingmaIpcProxy.exe start +``` + +The WinSW XML template lives at: + +- `scripts\lingma-ipc-proxy.xml.template` + ## Flags ```powershell diff --git a/scripts/build.ps1 b/scripts/build.ps1 new file mode 100644 index 0000000..28e0da9 --- /dev/null +++ b/scripts/build.ps1 @@ -0,0 +1,31 @@ +param( + [string]$OutputDir = "dist", + [string]$BinaryName = "lingma-ipc-proxy.exe", + [switch]$Clean +) + +$ErrorActionPreference = "Stop" + +$repoRoot = Split-Path -Parent $PSScriptRoot +$distDir = Join-Path $repoRoot $OutputDir +$binaryPath = Join-Path $distDir $BinaryName + +if ($Clean -and (Test-Path $distDir)) { + Remove-Item -Recurse -Force $distDir +} + +New-Item -ItemType Directory -Force $distDir | Out-Null + +Push-Location $repoRoot +try { + $env:CGO_ENABLED = "0" + $env:GOOS = "windows" + $env:GOARCH = "amd64" + + Write-Host "Building $binaryPath" + go build -trimpath -ldflags "-s -w" -o $binaryPath .\cmd\lingma-ipc-proxy + Write-Host "Build completed: $binaryPath" +} +finally { + Pop-Location +} diff --git a/scripts/install-nssm-service.ps1 b/scripts/install-nssm-service.ps1 new file mode 100644 index 0000000..1cceb01 --- /dev/null +++ b/scripts/install-nssm-service.ps1 @@ -0,0 +1,32 @@ +param( + [string]$ServiceName = "LingmaIpcProxy", + [string]$BinaryPath = "", + [string]$Arguments = "--host 127.0.0.1 --port 8095 --session-mode auto", + [string]$WorkingDirectory = "", + [string]$NssmPath = "nssm.exe", + [string]$Description = "Lingma IPC proxy service" +) + +$ErrorActionPreference = "Stop" + +$repoRoot = Split-Path -Parent $PSScriptRoot + +if ([string]::IsNullOrWhiteSpace($BinaryPath)) { + $BinaryPath = Join-Path $repoRoot "dist\lingma-ipc-proxy.exe" +} +if ([string]::IsNullOrWhiteSpace($WorkingDirectory)) { + $WorkingDirectory = $repoRoot +} + +if (!(Test-Path $BinaryPath)) { + throw "Binary not found: $BinaryPath" +} + +Write-Host "Installing NSSM service: $ServiceName" +& $NssmPath install $ServiceName $BinaryPath $Arguments +& $NssmPath set $ServiceName AppDirectory $WorkingDirectory +& $NssmPath set $ServiceName Description $Description +& $NssmPath set $ServiceName Start SERVICE_AUTO_START + +Write-Host "Service installed. Start with:" +Write-Host " $NssmPath start $ServiceName" diff --git a/scripts/install-winsw-service.ps1 b/scripts/install-winsw-service.ps1 new file mode 100644 index 0000000..89e1aeb --- /dev/null +++ b/scripts/install-winsw-service.ps1 @@ -0,0 +1,59 @@ +param( + [string]$ServiceName = "LingmaIpcProxy", + [string]$BinaryPath = "", + [string]$Arguments = "--host 127.0.0.1 --port 8095 --session-mode auto", + [string]$WorkingDirectory = "", + [string]$WinSWExePath = "", + [string]$TemplatePath = "" +) + +$ErrorActionPreference = "Stop" + +$repoRoot = Split-Path -Parent $PSScriptRoot + +if ([string]::IsNullOrWhiteSpace($BinaryPath)) { + $BinaryPath = Join-Path $repoRoot "dist\lingma-ipc-proxy.exe" +} +if ([string]::IsNullOrWhiteSpace($WorkingDirectory)) { + $WorkingDirectory = $repoRoot +} +if ([string]::IsNullOrWhiteSpace($WinSWExePath)) { + $WinSWExePath = Join-Path $repoRoot "dist\WinSW-x64.exe" +} +if ([string]::IsNullOrWhiteSpace($TemplatePath)) { + $TemplatePath = Join-Path $PSScriptRoot "lingma-ipc-proxy.xml.template" +} + +if (!(Test-Path $BinaryPath)) { + throw "Binary not found: $BinaryPath" +} +if (!(Test-Path $WinSWExePath)) { + throw "WinSW executable not found: $WinSWExePath" +} +if (!(Test-Path $TemplatePath)) { + throw "WinSW template not found: $TemplatePath" +} + +$serviceExePath = Join-Path $repoRoot "$ServiceName.exe" +$serviceXmlPath = Join-Path $repoRoot "$ServiceName.xml" + +$xml = Get-Content -Raw $TemplatePath +$xml = $xml.Replace("__SERVICE_ID__", $ServiceName) +$xml = $xml.Replace("__SERVICE_NAME__", $ServiceName) +$xml = $xml.Replace("__SERVICE_DESCRIPTION__", "Lingma IPC proxy service") +$xml = $xml.Replace("__EXECUTABLE__", $BinaryPath) +$xml = $xml.Replace("__ARGUMENTS__", $Arguments) +$xml = $xml.Replace("__WORKDIR__", $WorkingDirectory) +$xml = $xml.Replace("__LOGDIR__", (Join-Path $repoRoot "logs")) + +Copy-Item -Force $WinSWExePath $serviceExePath +Set-Content -Path $serviceXmlPath -Value $xml + +Write-Host "Prepared WinSW service wrapper:" +Write-Host " $serviceExePath" +Write-Host " $serviceXmlPath" +Write-Host "" +Write-Host "Install with:" +Write-Host " & `"$serviceExePath`" install" +Write-Host "Start with:" +Write-Host " & `"$serviceExePath`" start" diff --git a/scripts/lingma-ipc-proxy.xml.template b/scripts/lingma-ipc-proxy.xml.template new file mode 100644 index 0000000..e742ca4 --- /dev/null +++ b/scripts/lingma-ipc-proxy.xml.template @@ -0,0 +1,15 @@ + + __SERVICE_ID__ + __SERVICE_NAME__ + __SERVICE_DESCRIPTION__ + __EXECUTABLE__ + __ARGUMENTS__ + __WORKDIR__ + __LOGDIR__ + + 10485760 + 5 + + Automatic + 15sec +