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