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