svc_windows.go 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. // Copyright 2015 Daniel Theophanes.
  2. // Use of this source code is governed by a zlib-style
  3. // license that can be found in the LICENSE file.package service
  4. //+build windows
  5. package minwinsvc
  6. import (
  7. "os"
  8. "sync"
  9. "golang.org/x/sys/windows/svc"
  10. )
  11. var (
  12. onExit func()
  13. guard sync.Mutex
  14. )
  15. func init() {
  16. interactive, err := svc.IsAnInteractiveSession()
  17. if err != nil {
  18. panic(err)
  19. }
  20. if interactive {
  21. return
  22. }
  23. go func() {
  24. _ = svc.Run("", runner{})
  25. guard.Lock()
  26. f := onExit
  27. guard.Unlock()
  28. // Don't hold this lock in user code.
  29. if f != nil {
  30. f()
  31. }
  32. // Make sure we exit.
  33. os.Exit(0)
  34. }()
  35. }
  36. func setOnExit(f func()) {
  37. guard.Lock()
  38. onExit = f
  39. guard.Unlock()
  40. }
  41. type runner struct{}
  42. func (runner) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) {
  43. const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
  44. changes <- svc.Status{State: svc.StartPending}
  45. changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
  46. for {
  47. c := <-r
  48. switch c.Cmd {
  49. case svc.Interrogate:
  50. changes <- c.CurrentStatus
  51. case svc.Stop, svc.Shutdown:
  52. changes <- svc.Status{State: svc.StopPending}
  53. return false, 0
  54. }
  55. }
  56. return false, 0
  57. }