Smail/backend/cmd/smail/run_windows.go
smail f60d3b0880
Some checks are pending
Security Checks / security (push) Waiting to run
整理前后端与测试构建目录并完善配置和安全引导
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
2026-09-05 19:19:52 +08:00

76 lines
1.6 KiB
Go

//go:build windows
package main
import (
"time"
"git.pcux.cn/xuans/Smail/internal/app"
"git.pcux.cn/xuans/Smail/signal"
"golang.org/x/sys/windows/svc"
)
func runMain() error {
windowsServiceMode, err := svc.IsWindowsService()
if err != nil {
return err
}
if !windowsServiceMode {
return app.RecoverPanic(app.Run)
}
return svc.Run("Smail", &windowsService{})
}
type windowsService struct{}
func (windowsService) Execute(_ []string, requests <-chan svc.ChangeRequest, status chan<- svc.Status) (bool, uint32) {
const accepts = svc.AcceptStop | svc.AcceptShutdown
status <- svc.Status{State: svc.StartPending}
done := make(chan error, 1)
go func() {
done <- app.RecoverPanic(app.Run)
}()
status <- svc.Status{State: svc.Running, Accepts: accepts}
for {
select {
case err := <-done:
if err != nil {
return false, 1
}
status <- svc.Status{State: svc.StopPending}
return false, 0
case request, ok := <-requests:
if !ok {
return false, 0
}
switch request.Cmd {
case svc.Interrogate:
status <- svc.Status{State: svc.Running, Accepts: accepts}
case svc.Stop, svc.Shutdown:
return windowsServiceStop(done, status)
}
}
}
}
func windowsServiceStop(done <-chan error, status chan<- svc.Status) (bool, uint32) {
status <- svc.Status{State: svc.StopPending, WaitHint: 30_000}
select {
case signal.StopChan <- true:
case <-time.After(2 * time.Second):
return false, 1
}
select {
case err := <-done:
if err != nil {
return false, 1
}
return false, 0
case <-time.After(30 * time.Second):
return false, 1
}
}