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  }