daily pastebin goal
91%
SHARE
TWEET

Untitled

a guest Jun 10th, 2018 73 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. // +build windows
  6.  
  7. package main
  8.  
  9. import (
  10.     "fmt"
  11.     "strings"
  12.     "time"
  13.     "syscall"
  14.  
  15.     "golang.org/x/sys/windows/svc"
  16.     "golang.org/x/sys/windows/svc/mgr"
  17.     "golang.org/x/sys/windows/svc/debug"
  18.     "log"
  19.     "os"
  20.     "path/filepath"
  21.     "golang.org/x/sys/windows/svc/eventlog"
  22. )
  23.  
  24. var elog debug.Log
  25.  
  26. type myservice struct{}
  27.  
  28. func (m *myservice) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
  29.     const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown | svc.AcceptPauseAndContinue
  30.     changes <- svc.Status{State: svc.StartPending}
  31.     fasttick := time.Tick(500 * time.Millisecond)
  32.     slowtick := time.Tick(2 * time.Second)
  33.     tick := fasttick
  34.     changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
  35.     elog.Info(1, strings.Join(args, "-"))
  36. loop:
  37.     for {
  38.         select {
  39.         case <-tick:
  40.             beep()
  41.             elog.Info(1, "beep")
  42.         case c := <-r:
  43.             switch c.Cmd {
  44.             case svc.Interrogate:
  45.                 changes <- c.CurrentStatus
  46.                 // Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
  47.                 time.Sleep(100 * time.Millisecond)
  48.                 changes <- c.CurrentStatus
  49.             case svc.Stop, svc.Shutdown:
  50.                 break loop
  51.             case svc.Pause:
  52.                 changes <- svc.Status{State: svc.Paused, Accepts: cmdsAccepted}
  53.                 tick = slowtick
  54.             case svc.Continue:
  55.                 changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
  56.                 tick = fasttick
  57.             default:
  58.                 elog.Error(1, fmt.Sprintf("unexpected control request #%d", c))
  59.             }
  60.         }
  61.     }
  62.     changes <- svc.Status{State: svc.StopPending}
  63.     return
  64. }
  65.  
  66. func runService(name string, isDebug bool) {
  67.     var err error
  68.     if isDebug {
  69.         elog = debug.New(name)
  70.     } else {
  71.         elog, err = eventlog.Open(name)
  72.         if err != nil {
  73.             return
  74.         }
  75.     }
  76.     defer elog.Close()
  77.  
  78.     elog.Info(1, fmt.Sprintf("starting %s service", name))
  79.     run := svc.Run
  80.     if isDebug {
  81.         run = debug.Run
  82.     }
  83.     err = run(name, &myservice{})
  84.     if err != nil {
  85.         elog.Error(1, fmt.Sprintf("%s service failed: %v", name, err))
  86.         return
  87.     }
  88.     elog.Info(1, fmt.Sprintf("%s service stopped", name))
  89. }
  90.  
  91. func startService(name string) error {
  92.     m, err := mgr.Connect()
  93.     if err != nil {
  94.         return err
  95.     }
  96.     defer m.Disconnect()
  97.     s, err := m.OpenService(name)
  98.     if err != nil {
  99.         return fmt.Errorf("could not access service: %v", err)
  100.     }
  101.     defer s.Close()
  102.     err = s.Start("is", "auto-started")
  103.     if err != nil {
  104.         return fmt.Errorf("could not start service: %v", err)
  105.     }
  106.     return nil
  107. }
  108.  
  109. func controlService(name string, c svc.Cmd, to svc.State) error {
  110.     m, err := mgr.Connect()
  111.     if err != nil {
  112.         return err
  113.     }
  114.     defer m.Disconnect()
  115.     s, err := m.OpenService(name)
  116.     if err != nil {
  117.         return fmt.Errorf("could not access service: %v", err)
  118.     }
  119.     defer s.Close()
  120.     status, err := s.Control(c)
  121.     if err != nil {
  122.         return fmt.Errorf("could not send control=%d: %v", c, err)
  123.     }
  124.     timeout := time.Now().Add(10 * time.Second)
  125.     for status.State != to {
  126.         if timeout.Before(time.Now()) {
  127.             return fmt.Errorf("timeout waiting for service to go to state=%d", to)
  128.         }
  129.         time.Sleep(300 * time.Millisecond)
  130.         status, err = s.Query()
  131.         if err != nil {
  132.             return fmt.Errorf("could not retrieve service status: %v", err)
  133.         }
  134.     }
  135.     return nil
  136. }
  137.  
  138. func main() {
  139.     const svcName = "Best Service"
  140.  
  141.     isIntSess, err := svc.IsAnInteractiveSession()
  142.     if err != nil {
  143.         log.Fatalf("failed to determine if we are running in an interactive session: %v", err)
  144.     }
  145.     if !isIntSess {
  146.         runService(svcName, false)
  147.         return
  148.     }
  149.  
  150.     /*err = controlService(svcName, svc.Stop, svc.Stopped)
  151.     err = removeService(svcName)*/
  152.     err = installService(svcName, "Best Service")
  153.     runService(svcName, true)
  154.  
  155.     if err != nil {
  156.         log.Fatalf("failed to %s: %v", svcName, err)
  157.     }
  158.     return
  159. }
  160.  
  161. func exePath() (string, error) {
  162.     prog := os.Args[0]
  163.     p, err := filepath.Abs(prog)
  164.     if err != nil {
  165.         return "", err
  166.     }
  167.     fi, err := os.Stat(p)
  168.     if err == nil {
  169.         if !fi.Mode().IsDir() {
  170.             return p, nil
  171.         }
  172.         err = fmt.Errorf("%s is directory", p)
  173.     }
  174.     if filepath.Ext(p) == "" {
  175.         p += ".exe"
  176.         fi, err := os.Stat(p)
  177.         if err == nil {
  178.             if !fi.Mode().IsDir() {
  179.                 return p, nil
  180.             }
  181.             err = fmt.Errorf("%s is directory", p)
  182.         }
  183.     }
  184.     return "", err
  185. }
  186.  
  187. func installService(name, desc string) error {
  188.     exepath, err := exePath()
  189.     if err != nil {
  190.         return err
  191.     }
  192.     m, err := mgr.Connect()
  193.     if err != nil {
  194.         return err
  195.     }
  196.     defer m.Disconnect()
  197.     s, err := m.OpenService(name)
  198.     if err == nil {
  199.         s.Close()
  200.         return fmt.Errorf("service %s already exists", name)
  201.     }
  202.     s, err = m.CreateService(name, exepath, mgr.Config{DisplayName: desc, Description: "BB service"}, "is", "auto-started")
  203.     if err != nil {
  204.         return err
  205.     }
  206.     defer s.Close()
  207.     err = eventlog.InstallAsEventCreate(name, eventlog.Error|eventlog.Warning|eventlog.Info)
  208.     if err != nil {
  209.         s.Delete()
  210.         return fmt.Errorf("SetupEventLogSource() failed: %s", err)
  211.     }
  212.     return nil
  213. }
  214.  
  215. func removeService(name string) error {
  216.     m, err := mgr.Connect()
  217.     if err != nil {
  218.         return err
  219.     }
  220.     defer m.Disconnect()
  221.     s, err := m.OpenService(name)
  222.     if err != nil {
  223.         return fmt.Errorf("service %s is not installed", name)
  224.     }
  225.     defer s.Close()
  226.     err = s.Delete()
  227.     if err != nil {
  228.         return err
  229.     }
  230.     err = eventlog.Remove(name)
  231.     if err != nil {
  232.         return fmt.Errorf("RemoveEventLogSource() failed: %s", err)
  233.     }
  234.     return nil
  235. }
  236.  
  237. var (
  238.     beepFunc = syscall.MustLoadDLL("user32.dll").MustFindProc("MessageBeep")
  239. )
  240.  
  241. func beep() {
  242.     beepFunc.Call(0xffffffff)
  243. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top