github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/osext/winsvc/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  // Package mgr can be used to manage Windows service programs.
     6  // It can be used to install and remove them. It can also start,
     7  // stop, pause and so on. It can query current service state.
     8  // It can query service config parameters and change them.
     9  //
    10  package mgr
    11  
    12  import (
    13  	"chai2010.gopkg/osext/winsvc/winapi"
    14  	"syscall"
    15  )
    16  
    17  // Mgr is used to manage Windows service.
    18  type Mgr struct {
    19  	Handle syscall.Handle
    20  }
    21  
    22  // Connect establishes a connection to the service control manager.
    23  func Connect() (*Mgr, error) {
    24  	return ConnectRemote("")
    25  }
    26  
    27  // ConnectRemote establishes a connection to the
    28  // service control manager on computer named host.
    29  func ConnectRemote(host string) (*Mgr, error) {
    30  	var s *uint16
    31  	if host != "" {
    32  		s = syscall.StringToUTF16Ptr(host)
    33  	}
    34  	h, err := winapi.OpenSCManager(s, nil, winapi.SC_MANAGER_ALL_ACCESS)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	return &Mgr{Handle: h}, nil
    39  }
    40  
    41  // Disconnect closes connection m to servise control manager.
    42  func (m *Mgr) Disconnect() error {
    43  	return winapi.CloseServiceHandle(m.Handle)
    44  }
    45  
    46  func toPtr(s string) *uint16 {
    47  	if len(s) == 0 {
    48  		return nil
    49  	}
    50  	return syscall.StringToUTF16Ptr(s)
    51  }
    52  
    53  // CreateService installs new service name on the system.
    54  // The service will be executed by running exepath binary,
    55  // while service settings are specified in config c.
    56  func (m *Mgr) CreateService(name, exepath string, c Config) (*Service, error) {
    57  	if c.StartType == 0 {
    58  		c.StartType = StartManual
    59  	}
    60  	if c.ErrorControl == 0 {
    61  		c.ErrorControl = ErrorNormal
    62  	}
    63  	c.BinaryPathName = exepath // execpath is important, do not rely on BinaryPathName field to be set
    64  	h, err := winapi.CreateService(m.Handle, toPtr(name), toPtr(c.DisplayName),
    65  		winapi.SERVICE_ALL_ACCESS, winapi.SERVICE_WIN32_OWN_PROCESS,
    66  		c.StartType, c.ErrorControl, toPtr(exepath), toPtr(c.LoadOrderGroup),
    67  		nil, toPtr(c.Dependencies), toPtr(c.ServiceStartName), toPtr(c.Password))
    68  	if err != nil {
    69  		return nil, err
    70  	}
    71  	if c.Description != "" {
    72  		err = updateDescription(h, c.Description)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  	}
    77  	return &Service{Name: name, Handle: h}, nil
    78  }
    79  
    80  // OpenService retrievs access to service name, so it can
    81  // be interrogated and controlled.
    82  func (m *Mgr) OpenService(name string) (*Service, error) {
    83  	h, err := winapi.OpenService(m.Handle, syscall.StringToUTF16Ptr(name), winapi.SERVICE_ALL_ACCESS)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	return &Service{Name: name, Handle: h}, nil
    88  }