github.com/maenmax/kairep@v0.0.0-20210218001208-55bf3df36788/src/golang.org/x/sys/windows/svc/mgr/mgr.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 // +build windows 6 7 // Package mgr can be used to manage Windows service programs. 8 // It can be used to install and remove them. It can also start, 9 // stop and pause them. The package can query / change current 10 // service state and config parameters. 11 // 12 package mgr 13 14 import ( 15 "syscall" 16 "unicode/utf16" 17 18 "golang.org/x/sys/windows" 19 ) 20 21 // Mgr is used to manage Windows service. 22 type Mgr struct { 23 Handle windows.Handle 24 } 25 26 // Connect establishes a connection to the service control manager. 27 func Connect() (*Mgr, error) { 28 return ConnectRemote("") 29 } 30 31 // ConnectRemote establishes a connection to the 32 // service control manager on computer named host. 33 func ConnectRemote(host string) (*Mgr, error) { 34 var s *uint16 35 if host != "" { 36 s = syscall.StringToUTF16Ptr(host) 37 } 38 h, err := windows.OpenSCManager(s, nil, windows.SC_MANAGER_ALL_ACCESS) 39 if err != nil { 40 return nil, err 41 } 42 return &Mgr{Handle: h}, nil 43 } 44 45 // Disconnect closes connection to the service control manager m. 46 func (m *Mgr) Disconnect() error { 47 return windows.CloseServiceHandle(m.Handle) 48 } 49 50 func toPtr(s string) *uint16 { 51 if len(s) == 0 { 52 return nil 53 } 54 return syscall.StringToUTF16Ptr(s) 55 } 56 57 // toStringBlock terminates strings in ss with 0, and then 58 // concatenates them together. It also adds extra 0 at the end. 59 func toStringBlock(ss []string) *uint16 { 60 if len(ss) == 0 { 61 return nil 62 } 63 t := "" 64 for _, s := range ss { 65 if s != "" { 66 t += s + "\x00" 67 } 68 } 69 if t == "" { 70 return nil 71 } 72 t += "\x00" 73 return &utf16.Encode([]rune(t))[0] 74 } 75 76 // CreateService installs new service name on the system. 77 // The service will be executed by running exepath binary. 78 // Use config c to specify service parameters. 79 // If service StartType is set to StartAutomatic, 80 // args will be passed to svc.Handle.Execute. 81 func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Service, error) { 82 if c.StartType == 0 { 83 c.StartType = StartManual 84 } 85 if c.ErrorControl == 0 { 86 c.ErrorControl = ErrorNormal 87 } 88 if c.ServiceType == 0 { 89 c.ServiceType = windows.SERVICE_WIN32_OWN_PROCESS 90 } 91 s := syscall.EscapeArg(exepath) 92 for _, v := range args { 93 s += " " + syscall.EscapeArg(v) 94 } 95 h, err := windows.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName), 96 windows.SERVICE_ALL_ACCESS, c.ServiceType, 97 c.StartType, c.ErrorControl, toPtr(s), toPtr(c.LoadOrderGroup), 98 nil, toStringBlock(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password)) 99 if err != nil { 100 return nil, err 101 } 102 if c.Description != "" { 103 err = updateDescription(h, c.Description) 104 if err != nil { 105 return nil, err 106 } 107 } 108 return &Service{Name: name, Handle: h}, nil 109 } 110 111 // OpenService retrieves access to service name, so it can 112 // be interrogated and controlled. 113 func (m *Mgr) OpenService(name string) (*Service, error) { 114 h, err := windows.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), windows.SERVICE_ALL_ACCESS) 115 if err != nil { 116 return nil, err 117 } 118 return &Service{Name: name, Handle: h}, nil 119 }