Some checks are pending
Security Checks / security (push) Waiting to run
统一 frontend、backend、test、test-log 和 out 目录,更新构建、部署及测试入口;纳入配置管理兼容与首次安全引导修复;排除本机配置、密钥和测试产物。
76 lines
1.6 KiB
Go
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
|
|
}
|
|
}
|