| // Copyright 2012 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // +build windows | |
| package main | |
| import ( | |
| "fmt" | |
| "strings" | |
| "time" | |
| "golang.org/x/sys/windows/svc" | |
| "golang.org/x/sys/windows/svc/debug" | |
| "golang.org/x/sys/windows/svc/eventlog" | |
| ) | |
| var elog debug.Log | |
| type myservice struct{} | |
| func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) { | |
| const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue | |
| changes <- svc.Status{State: svc.StartPending} | |
| fasttick := time.Tick(500 * time.Millisecond) | |
| slowtick := time.Tick(2 * time.Second) | |
| tick := fasttick | |
| changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} | |
| loop: | |
| for { | |
| select { | |
| case <-tick: | |
| beep() | |
| elog.Info(1, "beep") | |
| case c := <-r: | |
| switch c.Cmd { | |
| case svc.Interrogate: | |
| changes <- c.CurrentStatus | |
| // Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4 | |
| time.Sleep(100 * time.Millisecond) | |
| changes <- c.CurrentStatus | |
| case svc.Stop, svc.Shutdown: | |
| // golang.org/x/sys/windows/svc.TestExample is verifying this output. | |
| testOutput := strings.Join(args, "-") | |
| testOutput += fmt.Sprintf("-%d", c.Context) | |
| elog.Info(1, testOutput) | |
| break loop | |
| case svc.Pause: | |
| changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted} | |
| tick = slowtick | |
| case svc.Continue: | |
| changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted} | |
| tick = fasttick | |
| default: | |
| elog.Error(1, fmt.Sprintf("unexpected control request #%d", c)) | |
| } | |
| } | |
| } | |
| changes <- svc.Status{State: svc.StopPending} | |
| return | |
| } | |
| func runService(name string, isDebug bool) { | |
| var err error | |
| if isDebug { | |
| elog = debug.New(name) | |
| } else { | |
| elog, err = eventlog.Open(name) | |
| if err != nil { | |
| return | |
| } | |
| } | |
| defer elog.Close() | |
| elog.Info(1, fmt.Sprintf("starting %s service", name)) | |
| run := svc.Run | |
| if isDebug { | |
| run = debug.Run | |
| } | |
| err = run(name, &myservice{}) | |
| if err != nil { | |
| elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err)) | |
| return | |
| } | |
| elog.Info(1, fmt.Sprintf("%s service stopped", name)) | |
| } |