service.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build windows
  5. package main
  6. import (
  7. "fmt"
  8. "strings"
  9. "time"
  10. "golang.org/x/sys/windows/svc"
  11. "golang.org/x/sys/windows/svc/debug"
  12. "golang.org/x/sys/windows/svc/eventlog"
  13. )
  14. var elog debug.Log
  15. type myservice struct{}
  16. func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
  17. const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
  18. changes <- svc.Status{State: svc.StartPending}
  19. fasttick := time.Tick(500 * time.Millisecond)
  20. slowtick := time.Tick(2 * time.Second)
  21. tick := fasttick
  22. changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
  23. loop:
  24. for {
  25. select {
  26. case <-tick:
  27. beep()
  28. elog.Info(1, "beep")
  29. case c := <-r:
  30. switch c.Cmd {
  31. case svc.Interrogate:
  32. changes <- c.CurrentStatus
  33. // Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
  34. time.Sleep(100 * time.Millisecond)
  35. changes <- c.CurrentStatus
  36. case svc.Stop, svc.Shutdown:
  37. // golang.org/x/sys/windows/svc.TestExample is verifying this output.
  38. testOutput := strings.Join(args, "-")
  39. testOutput += fmt.Sprintf("-%d", c.Context)
  40. elog.Info(1, testOutput)
  41. break loop
  42. case svc.Pause:
  43. changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
  44. tick = slowtick
  45. case svc.Continue:
  46. changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
  47. tick = fasttick
  48. default:
  49. elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
  50. }
  51. }
  52. }
  53. changes <- svc.Status{State: svc.StopPending}
  54. return
  55. }
  56. func runService(name string, isDebug bool) {
  57. var err error
  58. if isDebug {
  59. elog = debug.New(name)
  60. } else {
  61. elog, err = eventlog.Open(name)
  62. if err != nil {
  63. return
  64. }
  65. }
  66. defer elog.Close()
  67. elog.Info(1, fmt.Sprintf("starting %s service", name))
  68. run := svc.Run
  69. if isDebug {
  70. run = debug.Run
  71. }
  72. err = run(name, &myservice{})
  73. if err != nil {
  74. elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
  75. return
  76. }
  77. elog.Info(1, fmt.Sprintf("%s service stopped", name))
  78. }