mirror of
https://github.com/golang/sys.git
synced 2026-02-08 11:46:04 +03:00
windows: add support for automatic delayed start in windows service
Change-Id: Iad33ea0f6627ac98c89dbaab0b41b3dd724c3163
GitHub-Last-Rev: 8764fdbd32
GitHub-Pull-Request: golang/sys#36
Reviewed-on: https://go-review.googlesource.com/c/sys/+/187198
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
committed by
Alex Brainman
parent
cbf593c0f2
commit
51ab0e2dea
@@ -159,6 +159,10 @@ type SERVICE_DESCRIPTION struct {
|
||||
Description *uint16
|
||||
}
|
||||
|
||||
type SERVICE_DELAYED_AUTO_START_INFO struct {
|
||||
IsDelayedAutoStartUp uint32
|
||||
}
|
||||
|
||||
type SERVICE_STATUS_PROCESS struct {
|
||||
ServiceType uint32
|
||||
CurrentState uint32
|
||||
|
||||
@@ -43,6 +43,7 @@ type Config struct {
|
||||
Password string
|
||||
Description string
|
||||
SidType uint32 // one of SERVICE_SID_TYPE, the type of sid to use for the service
|
||||
DelayedAutoStart bool // the service is started after other auto-start services are started plus a short delay
|
||||
}
|
||||
|
||||
func toString(p *uint16) string {
|
||||
@@ -95,6 +96,16 @@ func (s *Service) Config() (Config, error) {
|
||||
}
|
||||
p2 := (*windows.SERVICE_DESCRIPTION)(unsafe.Pointer(&b[0]))
|
||||
|
||||
b, err = s.queryServiceConfig2(windows.SERVICE_CONFIG_DELAYED_AUTO_START_INFO)
|
||||
if err != nil {
|
||||
return Config{}, err
|
||||
}
|
||||
p3 := (*windows.SERVICE_DELAYED_AUTO_START_INFO)(unsafe.Pointer(&b[0]))
|
||||
delayedStart := false
|
||||
if p3.IsDelayedAutoStartUp != 0 {
|
||||
delayedStart = true
|
||||
}
|
||||
|
||||
return Config{
|
||||
ServiceType: p.ServiceType,
|
||||
StartType: p.StartType,
|
||||
@@ -106,6 +117,7 @@ func (s *Service) Config() (Config, error) {
|
||||
ServiceStartName: toString(p.ServiceStartName),
|
||||
DisplayName: toString(p.DisplayName),
|
||||
Description: toString(p2.Description),
|
||||
DelayedAutoStart: delayedStart,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -119,6 +131,15 @@ func updateSidType(handle windows.Handle, sidType uint32) error {
|
||||
return windows.ChangeServiceConfig2(handle, windows.SERVICE_CONFIG_SERVICE_SID_INFO, (*byte)(unsafe.Pointer(&sidType)))
|
||||
}
|
||||
|
||||
func updateStartUp(handle windows.Handle, isDelayed bool) error {
|
||||
var d windows.SERVICE_DELAYED_AUTO_START_INFO
|
||||
if isDelayed {
|
||||
d.IsDelayedAutoStartUp = 1
|
||||
}
|
||||
return windows.ChangeServiceConfig2(handle,
|
||||
windows.SERVICE_CONFIG_DELAYED_AUTO_START_INFO, (*byte)(unsafe.Pointer(&d)))
|
||||
}
|
||||
|
||||
// UpdateConfig updates service s configuration parameters.
|
||||
func (s *Service) UpdateConfig(c Config) error {
|
||||
err := windows.ChangeServiceConfig(s.Handle, c.ServiceType, c.StartType,
|
||||
@@ -132,6 +153,12 @@ func (s *Service) UpdateConfig(c Config) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = updateStartUp(s.Handle, c.DelayedAutoStart)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return updateDescription(s.Handle, c.Description)
|
||||
}
|
||||
|
||||
|
||||
@@ -149,6 +149,14 @@ func (m *Mgr) CreateService(name, exepath string, c Config, args ...string) (*Se
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if c.DelayedAutoStart {
|
||||
err = updateStartUp(h, c.DelayedAutoStart)
|
||||
if err != nil {
|
||||
windows.DeleteService(h)
|
||||
windows.CloseHandle(h)
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return &Service{Name: name, Handle: h}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -80,6 +80,9 @@ func testConfig(t *testing.T, s *mgr.Service, should mgr.Config) mgr.Config {
|
||||
if err != nil {
|
||||
t.Fatalf("Config failed: %s", err)
|
||||
}
|
||||
if should.DelayedAutoStart != is.DelayedAutoStart {
|
||||
t.Fatalf("config mismatch: DelayedAutoStart is %v, but should have %v", is.DelayedAutoStart, should.DelayedAutoStart)
|
||||
}
|
||||
if should.DisplayName != is.DisplayName {
|
||||
t.Fatalf("config mismatch: DisplayName is %q, but should have %q", is.DisplayName, should.DisplayName)
|
||||
}
|
||||
@@ -257,6 +260,15 @@ func TestMyService(t *testing.T) {
|
||||
|
||||
testConfig(t, s, c)
|
||||
|
||||
c.StartType = mgr.StartAutomatic
|
||||
c.DelayedAutoStart = true
|
||||
err = s.UpdateConfig(c)
|
||||
if err != nil {
|
||||
t.Fatalf("UpdateConfig failed: %v", err)
|
||||
}
|
||||
|
||||
testConfig(t, s, c)
|
||||
|
||||
svcnames, err := m.ListServices()
|
||||
if err != nil {
|
||||
t.Fatalf("ListServices failed: %v", err)
|
||||
|
||||
Reference in New Issue
Block a user