From c28303099b95edbef71faec1c624fc318d4b9b86 Mon Sep 17 00:00:00 2001 From: krysennn Date: Sat, 17 Mar 2018 00:41:53 +0100 Subject: [PATCH 1/6] Remove nssm for generic sc command && add error mgmt from microsoft --- daemon_windows.go | 69 +++++++++++++++----------- helper.go | 121 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 161 insertions(+), 29 deletions(-) diff --git a/daemon_windows.go b/daemon_windows.go index 8d92cb5..ea1ec4b 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -12,10 +12,9 @@ import ( "syscall" "unicode/utf16" "unsafe" + "regexp" ) -var ErrWindowsUnsupported = errors.New("Adding as a service failed. Download and place nssm.exe in the path to install this service as an service. NSSM url: https://nssm.cc/") - // windowsRecord - standard record (struct) for windows version of daemon package type windowsRecord struct { name string @@ -31,7 +30,6 @@ func newDaemon(name, description string, dependencies []string) (Daemon, error) // Install the service func (windows *windowsRecord) Install(args ...string) (string, error) { installAction := "Install " + windows.description + ":" - adminAccessNecessary := "Administrator access is needed to install a service." execp, err := execPath() @@ -39,21 +37,15 @@ func (windows *windowsRecord) Install(args ...string) (string, error) { return installAction + failed, err } - cmdArgs := []string{"install", windows.name, execp} + cmdArgs := []string{"create", windows.name, "start=auto", "binPath="+execp} cmdArgs = append(cmdArgs, args...) - cmd := exec.Command("nssm.exe", cmdArgs...) - out, err := cmd.Output() - if err != nil { - if len(out) > 0 { - fmt.Println(string(out)) - } else { - fmt.Println("No output. Probably service already exists. Try uninstall first.") + cmd := exec.Command("sc", cmdArgs...) + _, err = cmd.Output() + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + return installAction + failed, getWindowsError(status.ExitCode) } - return installAction + failed, err - } - if len(out) == 0 { - return adminAccessNecessary, errors.New(adminAccessNecessary) } return installAction + " completed.", nil } @@ -61,10 +53,12 @@ func (windows *windowsRecord) Install(args ...string) (string, error) { // Remove the service func (windows *windowsRecord) Remove() (string, error) { removeAction := "Removing " + windows.description + ":" - cmd := exec.Command("nssm.exe", "remove", windows.name, "confirm") + cmd := exec.Command("sc", "delete", windows.name, "confirm") err := cmd.Run() - if err != nil { - return removeAction + failed, err + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + return removeAction + failed, getWindowsError(status.ExitCode) + } } return removeAction + " completed.", nil } @@ -72,10 +66,12 @@ func (windows *windowsRecord) Remove() (string, error) { // Start the service func (windows *windowsRecord) Start() (string, error) { startAction := "Starting " + windows.description + ":" - cmd := exec.Command("nssm.exe", "start", windows.name) + cmd := exec.Command("sc", "start", windows.name) err := cmd.Run() - if err != nil { - return startAction + failed, err + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + return startAction + failed, getWindowsError(status.ExitCode) + } } return startAction + " completed.", nil } @@ -83,22 +79,26 @@ func (windows *windowsRecord) Start() (string, error) { // Stop the service func (windows *windowsRecord) Stop() (string, error) { stopAction := "Stopping " + windows.description + ":" - cmd := exec.Command("nssm.exe", "stop", windows.name) + cmd := exec.Command("sc", "stop", windows.name) err := cmd.Run() - if err != nil { - return stopAction + failed, err + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + return stopAction + failed, getWindowsError(status.ExitCode) + } } return stopAction + " completed.", nil } // Status - Get service status func (windows *windowsRecord) Status() (string, error) { - cmd := exec.Command("nssm.exe", "status", windows.name) + cmd := exec.Command("sc", "query", windows.name) out, err := cmd.Output() - if err != nil { - return "Getting status:" + failed, err + if exiterr, ok := err.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + return "Getting status:" + failed, getWindowsError(status.ExitCode) + } } - return "Status: " + string(out), nil + return "Status: " + "SERVICE_"+getWindowsServiceState(out), nil } // Get executable path @@ -118,3 +118,16 @@ func execPath() (string, error) { } return string(utf16.Decode(b[0:n])), nil } + +// Get windows error +func getWindowsError(statusCode uint32) error { + return errors.New(fmt.Sprintf("\n %s: %s \n %s", WinErrCode[statusCode].Title, WinErrCode[statusCode].Description, WinErrCode[statusCode].Action)) +} + +// Get windows service state +func getWindowsServiceState(out []byte) string { + regex := regexp.MustCompile("STATE.*: (?P[0-9]) (?P.*) ") + service := regex.FindAllStringSubmatch(string(out), -1)[0] + + return service[2] +} \ No newline at end of file diff --git a/helper.go b/helper.go index 35981fb..a8fcff9 100644 --- a/helper.go +++ b/helper.go @@ -38,8 +38,127 @@ var ( // ErrAlreadyStopped appears if try to stop already stopped service ErrAlreadyStopped = errors.New("Service has already been stopped") + + // Windows Errors + WinErrCode = map[uint32]SystemError{ + 5: SystemError{ + Title: "ERROR_ACCESS_DENIED", + Description: "Access denied.", + Action: "Administrator access is needed to install a service.", + }, + 1051: SystemError{ + Title: "ERROR_DEPENDENT_SERVICES_RUNNING", + Description: "A stop control has been sent to a service that other running services are dependent on.", + }, + 1052: SystemError{ + Title: "ERROR_INVALID_SERVICE_CONTROL", + Description: "The requested control is not valid for this service.", + }, + 1053: SystemError{ + Title: "ERROR_SERVICE_REQUEST_TIMEOUT", + Description: "The service did not respond to the start or control request in a timely fashion.", + }, + 1054: SystemError{ + Title: "ERROR_SERVICE_NO_THREAD", + Description: "A thread could not be created for the service.", + }, + 1055: SystemError{ + Title: "ERROR_SERVICE_DATABASE_LOCKED", + Description: "The service database is locked.", + }, + 1056: SystemError{ + Title: "ERROR_SERVICE_ALREADY_RUNNING", + Description: "An instance of the service is already running.", + }, + 1057: SystemError{ + Title: "ERROR_INVALID_SERVICE_ACCOUNT", + Description: "The account name is invalid or does not exist, or the password is invalid for the account name specified.", + }, + 1058: SystemError{ + Title: "ERROR_SERVICE_DISABLED", + Description: "The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.", + }, + 1060: SystemError{ + Title: "ERROR_SERVICE_DOES_NOT_EXIST", + Description: "The specified service does not exist as an installed service.", + }, + 1061: SystemError{ + Title: "ERROR_SERVICE_CANNOT_ACCEPT_CTRL", + Description: "The service cannot accept control messages at this time.", + }, + 1062: SystemError{ + Title: "ERROR_SERVICE_NOT_ACTIVE", + Description: "The service has not been started.", + }, + 1063: SystemError{ + Title: "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT", + Description: "The service process could not connect to the service controller.", + }, + 1064: SystemError{ + Title: "ERROR_EXCEPTION_IN_SERVICE", + Description: "An exception occurred in the service when handling the control request.", + }, + 1066: SystemError{ + Title: "ERROR_SERVICE_SPECIFIC_ERROR", + Description: "The service has returned a service-specific error code.", + }, + 1068: SystemError{ + Title: "ERROR_SERVICE_DEPENDENCY_FAIL", + Description: "The dependency service or group failed to start.", + }, + 1069: SystemError{ + Title: "ERROR_SERVICE_LOGON_FAILED", + Description: "The service did not start due to a logon failure.", + }, + 1070: SystemError{ + Title: "ERROR_SERVICE_START_HANG", + Description: "After starting, the service hung in a start-pending state.", + }, + 1071: SystemError{ + Title: "ERROR_INVALID_SERVICE_LOCK", + Description: "The specified service database lock is invalid.", + }, + 1072: SystemError{ + Title: "ERROR_SERVICE_MARKED_FOR_DELETE", + Description: "The specified service has been marked for deletion.", + }, + 1073: SystemError{ + Title: "ERROR_SERVICE_EXISTS", + Description: "The specified service already exists.", + }, + 1075: SystemError{ + Title: "ERROR_SERVICE_DEPENDENCY_DELETED", + Description: "The dependency service does not exist or has been marked for deletion.", + }, + 1077: SystemError{ + Title: "ERROR_SERVICE_NEVER_STARTED", + Description: "No attempts to start the service have been made since the last boot.", + }, + 1078: SystemError{ + Title: "ERROR_DUPLICATE_SERVICE_NAME", + Description: "The name is already in use as either a service name or a service display name.", + }, + 1079: SystemError{ + Title: "ERROR_DIFFERENT_SERVICE_ACCOUNT", + Description: "The account specified for this service is different from the account specified for other services running in the same process.", + }, + 1083: SystemError{ + Title: "ERROR_SERVICE_NOT_IN_EXE", + Description: "The executable program that this service is configured to run in does not implement the service.", + }, + 1084: SystemError{ + Title: "ERROR_NOT_SAFEBOOT_SERVICE", + Description: "This service cannot be started in Safe Mode.", + }, + } ) +type SystemError struct { + Title string + Description string + Action string +} + // ExecPath tries to get executable path func ExecPath() (string, error) { return os.Executable() @@ -67,4 +186,4 @@ func checkPrivileges() (bool, error) { } } return false, ErrUnsupportedSystem -} +} \ No newline at end of file From cc1263daf45eb0e223b4f5856b48c80472aac39f Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Sat, 17 Mar 2018 11:29:14 +0700 Subject: [PATCH 2/6] move windows errors in os depended helper --- helper.go | 121 +------------------------------------------ helper_windows.go | 128 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+), 120 deletions(-) create mode 100644 helper_windows.go diff --git a/helper.go b/helper.go index a8fcff9..35981fb 100644 --- a/helper.go +++ b/helper.go @@ -38,127 +38,8 @@ var ( // ErrAlreadyStopped appears if try to stop already stopped service ErrAlreadyStopped = errors.New("Service has already been stopped") - - // Windows Errors - WinErrCode = map[uint32]SystemError{ - 5: SystemError{ - Title: "ERROR_ACCESS_DENIED", - Description: "Access denied.", - Action: "Administrator access is needed to install a service.", - }, - 1051: SystemError{ - Title: "ERROR_DEPENDENT_SERVICES_RUNNING", - Description: "A stop control has been sent to a service that other running services are dependent on.", - }, - 1052: SystemError{ - Title: "ERROR_INVALID_SERVICE_CONTROL", - Description: "The requested control is not valid for this service.", - }, - 1053: SystemError{ - Title: "ERROR_SERVICE_REQUEST_TIMEOUT", - Description: "The service did not respond to the start or control request in a timely fashion.", - }, - 1054: SystemError{ - Title: "ERROR_SERVICE_NO_THREAD", - Description: "A thread could not be created for the service.", - }, - 1055: SystemError{ - Title: "ERROR_SERVICE_DATABASE_LOCKED", - Description: "The service database is locked.", - }, - 1056: SystemError{ - Title: "ERROR_SERVICE_ALREADY_RUNNING", - Description: "An instance of the service is already running.", - }, - 1057: SystemError{ - Title: "ERROR_INVALID_SERVICE_ACCOUNT", - Description: "The account name is invalid or does not exist, or the password is invalid for the account name specified.", - }, - 1058: SystemError{ - Title: "ERROR_SERVICE_DISABLED", - Description: "The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.", - }, - 1060: SystemError{ - Title: "ERROR_SERVICE_DOES_NOT_EXIST", - Description: "The specified service does not exist as an installed service.", - }, - 1061: SystemError{ - Title: "ERROR_SERVICE_CANNOT_ACCEPT_CTRL", - Description: "The service cannot accept control messages at this time.", - }, - 1062: SystemError{ - Title: "ERROR_SERVICE_NOT_ACTIVE", - Description: "The service has not been started.", - }, - 1063: SystemError{ - Title: "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT", - Description: "The service process could not connect to the service controller.", - }, - 1064: SystemError{ - Title: "ERROR_EXCEPTION_IN_SERVICE", - Description: "An exception occurred in the service when handling the control request.", - }, - 1066: SystemError{ - Title: "ERROR_SERVICE_SPECIFIC_ERROR", - Description: "The service has returned a service-specific error code.", - }, - 1068: SystemError{ - Title: "ERROR_SERVICE_DEPENDENCY_FAIL", - Description: "The dependency service or group failed to start.", - }, - 1069: SystemError{ - Title: "ERROR_SERVICE_LOGON_FAILED", - Description: "The service did not start due to a logon failure.", - }, - 1070: SystemError{ - Title: "ERROR_SERVICE_START_HANG", - Description: "After starting, the service hung in a start-pending state.", - }, - 1071: SystemError{ - Title: "ERROR_INVALID_SERVICE_LOCK", - Description: "The specified service database lock is invalid.", - }, - 1072: SystemError{ - Title: "ERROR_SERVICE_MARKED_FOR_DELETE", - Description: "The specified service has been marked for deletion.", - }, - 1073: SystemError{ - Title: "ERROR_SERVICE_EXISTS", - Description: "The specified service already exists.", - }, - 1075: SystemError{ - Title: "ERROR_SERVICE_DEPENDENCY_DELETED", - Description: "The dependency service does not exist or has been marked for deletion.", - }, - 1077: SystemError{ - Title: "ERROR_SERVICE_NEVER_STARTED", - Description: "No attempts to start the service have been made since the last boot.", - }, - 1078: SystemError{ - Title: "ERROR_DUPLICATE_SERVICE_NAME", - Description: "The name is already in use as either a service name or a service display name.", - }, - 1079: SystemError{ - Title: "ERROR_DIFFERENT_SERVICE_ACCOUNT", - Description: "The account specified for this service is different from the account specified for other services running in the same process.", - }, - 1083: SystemError{ - Title: "ERROR_SERVICE_NOT_IN_EXE", - Description: "The executable program that this service is configured to run in does not implement the service.", - }, - 1084: SystemError{ - Title: "ERROR_NOT_SAFEBOOT_SERVICE", - Description: "This service cannot be started in Safe Mode.", - }, - } ) -type SystemError struct { - Title string - Description string - Action string -} - // ExecPath tries to get executable path func ExecPath() (string, error) { return os.Executable() @@ -186,4 +67,4 @@ func checkPrivileges() (bool, error) { } } return false, ErrUnsupportedSystem -} \ No newline at end of file +} diff --git a/helper_windows.go b/helper_windows.go new file mode 100644 index 0000000..5dd0e6a --- /dev/null +++ b/helper_windows.go @@ -0,0 +1,128 @@ +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by +// license that can be found in the LICENSE file. + +package daemon + +// SystemError contains error description and corresponded action helper to fix it +type SystemError struct { + Title string + Description string + Action string +} + +var ( + // WinErrCode - List of system errors from Microsoft source: + // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx + WinErrCode = map[uint32]SystemError{ + 5: SystemError{ + Title: "ERROR_ACCESS_DENIED", + Description: "Access denied.", + Action: "Administrator access is needed to install a service.", + }, + 1051: SystemError{ + Title: "ERROR_DEPENDENT_SERVICES_RUNNING", + Description: "A stop control has been sent to a service that other running services are dependent on.", + }, + 1052: SystemError{ + Title: "ERROR_INVALID_SERVICE_CONTROL", + Description: "The requested control is not valid for this service.", + }, + 1053: SystemError{ + Title: "ERROR_SERVICE_REQUEST_TIMEOUT", + Description: "The service did not respond to the start or control request in a timely fashion.", + }, + 1054: SystemError{ + Title: "ERROR_SERVICE_NO_THREAD", + Description: "A thread could not be created for the service.", + }, + 1055: SystemError{ + Title: "ERROR_SERVICE_DATABASE_LOCKED", + Description: "The service database is locked.", + }, + 1056: SystemError{ + Title: "ERROR_SERVICE_ALREADY_RUNNING", + Description: "An instance of the service is already running.", + }, + 1057: SystemError{ + Title: "ERROR_INVALID_SERVICE_ACCOUNT", + Description: "The account name is invalid or does not exist, or the password is invalid for the account name specified.", + }, + 1058: SystemError{ + Title: "ERROR_SERVICE_DISABLED", + Description: "The service cannot be started, either because it is disabled or because it has no enabled devices associated with it.", + }, + 1060: SystemError{ + Title: "ERROR_SERVICE_DOES_NOT_EXIST", + Description: "The specified service does not exist as an installed service.", + }, + 1061: SystemError{ + Title: "ERROR_SERVICE_CANNOT_ACCEPT_CTRL", + Description: "The service cannot accept control messages at this time.", + }, + 1062: SystemError{ + Title: "ERROR_SERVICE_NOT_ACTIVE", + Description: "The service has not been started.", + }, + 1063: SystemError{ + Title: "ERROR_FAILED_SERVICE_CONTROLLER_CONNECT", + Description: "The service process could not connect to the service controller.", + }, + 1064: SystemError{ + Title: "ERROR_EXCEPTION_IN_SERVICE", + Description: "An exception occurred in the service when handling the control request.", + }, + 1066: SystemError{ + Title: "ERROR_SERVICE_SPECIFIC_ERROR", + Description: "The service has returned a service-specific error code.", + }, + 1068: SystemError{ + Title: "ERROR_SERVICE_DEPENDENCY_FAIL", + Description: "The dependency service or group failed to start.", + }, + 1069: SystemError{ + Title: "ERROR_SERVICE_LOGON_FAILED", + Description: "The service did not start due to a logon failure.", + }, + 1070: SystemError{ + Title: "ERROR_SERVICE_START_HANG", + Description: "After starting, the service hung in a start-pending state.", + }, + 1071: SystemError{ + Title: "ERROR_INVALID_SERVICE_LOCK", + Description: "The specified service database lock is invalid.", + }, + 1072: SystemError{ + Title: "ERROR_SERVICE_MARKED_FOR_DELETE", + Description: "The specified service has been marked for deletion.", + }, + 1073: SystemError{ + Title: "ERROR_SERVICE_EXISTS", + Description: "The specified service already exists.", + }, + 1075: SystemError{ + Title: "ERROR_SERVICE_DEPENDENCY_DELETED", + Description: "The dependency service does not exist or has been marked for deletion.", + }, + 1077: SystemError{ + Title: "ERROR_SERVICE_NEVER_STARTED", + Description: "No attempts to start the service have been made since the last boot.", + }, + 1078: SystemError{ + Title: "ERROR_DUPLICATE_SERVICE_NAME", + Description: "The name is already in use as either a service name or a service display name.", + }, + 1079: SystemError{ + Title: "ERROR_DIFFERENT_SERVICE_ACCOUNT", + Description: "The account specified for this service is different from the account specified for other services running in the same process.", + }, + 1083: SystemError{ + Title: "ERROR_SERVICE_NOT_IN_EXE", + Description: "The executable program that this service is configured to run in does not implement the service.", + }, + 1084: SystemError{ + Title: "ERROR_NOT_SAFEBOOT_SERVICE", + Description: "This service cannot be started in Safe Mode.", + }, + } +) From 31ae19ac70fb26940270753adfdb9b4f3d84a0bc Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Sat, 17 Mar 2018 12:23:15 +0700 Subject: [PATCH 3/6] some improvements in windows depended daemon --- daemon_windows.go | 50 +++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/daemon_windows.go b/daemon_windows.go index ea1ec4b..6c1ffc9 100644 --- a/daemon_windows.go +++ b/daemon_windows.go @@ -9,10 +9,10 @@ import ( "errors" "fmt" "os/exec" + "regexp" "syscall" "unicode/utf16" "unsafe" - "regexp" ) // windowsRecord - standard record (struct) for windows version of daemon package @@ -37,15 +37,13 @@ func (windows *windowsRecord) Install(args ...string) (string, error) { return installAction + failed, err } - cmdArgs := []string{"create", windows.name, "start=auto", "binPath="+execp} + cmdArgs := []string{"create", windows.name, "start=auto", "binPath=" + execp} cmdArgs = append(cmdArgs, args...) cmd := exec.Command("sc", cmdArgs...) _, err = cmd.Output() - if exiterr, ok := err.(*exec.ExitError); ok { - if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { - return installAction + failed, getWindowsError(status.ExitCode) - } + if err != nil { + return installAction + failed, getWindowsError(err) } return installAction + " completed.", nil } @@ -55,10 +53,8 @@ func (windows *windowsRecord) Remove() (string, error) { removeAction := "Removing " + windows.description + ":" cmd := exec.Command("sc", "delete", windows.name, "confirm") err := cmd.Run() - if exiterr, ok := err.(*exec.ExitError); ok { - if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { - return removeAction + failed, getWindowsError(status.ExitCode) - } + if err != nil { + return removeAction + failed, getWindowsError(err) } return removeAction + " completed.", nil } @@ -68,10 +64,8 @@ func (windows *windowsRecord) Start() (string, error) { startAction := "Starting " + windows.description + ":" cmd := exec.Command("sc", "start", windows.name) err := cmd.Run() - if exiterr, ok := err.(*exec.ExitError); ok { - if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { - return startAction + failed, getWindowsError(status.ExitCode) - } + if err != nil { + return startAction + failed, getWindowsError(err) } return startAction + " completed.", nil } @@ -81,10 +75,8 @@ func (windows *windowsRecord) Stop() (string, error) { stopAction := "Stopping " + windows.description + ":" cmd := exec.Command("sc", "stop", windows.name) err := cmd.Run() - if exiterr, ok := err.(*exec.ExitError); ok { - if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { - return stopAction + failed, getWindowsError(status.ExitCode) - } + if err != nil { + return stopAction + failed, err } return stopAction + " completed.", nil } @@ -93,12 +85,10 @@ func (windows *windowsRecord) Stop() (string, error) { func (windows *windowsRecord) Status() (string, error) { cmd := exec.Command("sc", "query", windows.name) out, err := cmd.Output() - if exiterr, ok := err.(*exec.ExitError); ok { - if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { - return "Getting status:" + failed, getWindowsError(status.ExitCode) - } + if err != nil { + return "Getting status:" + failed, getWindowsError(err) } - return "Status: " + "SERVICE_"+getWindowsServiceState(out), nil + return "Status: " + "SERVICE_" + getWindowsServiceState(out), nil } // Get executable path @@ -120,8 +110,16 @@ func execPath() (string, error) { } // Get windows error -func getWindowsError(statusCode uint32) error { - return errors.New(fmt.Sprintf("\n %s: %s \n %s", WinErrCode[statusCode].Title, WinErrCode[statusCode].Description, WinErrCode[statusCode].Action)) +func getWindowsError(inputError error) error { + if exiterr, ok := inputError.(*exec.ExitError); ok { + if status, ok := exiterr.Sys().(syscall.WaitStatus); ok { + if sysErr, ok := WinErrCode[status.ExitStatus()]; ok { + return errors.New(fmt.Sprintf("\n %s: %s \n %s", sysErr.Title, sysErr.Description, sysErr.Action)) + } + } + } + + return inputError } // Get windows service state @@ -130,4 +128,4 @@ func getWindowsServiceState(out []byte) string { service := regex.FindAllStringSubmatch(string(out), -1)[0] return service[2] -} \ No newline at end of file +} From 9a00835032e906ee99468ecaa1c655f412f24da3 Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Sat, 17 Mar 2018 12:23:37 +0700 Subject: [PATCH 4/6] use int for compatibility --- helper_windows.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper_windows.go b/helper_windows.go index 5dd0e6a..12816bc 100644 --- a/helper_windows.go +++ b/helper_windows.go @@ -14,7 +14,7 @@ type SystemError struct { var ( // WinErrCode - List of system errors from Microsoft source: // https://msdn.microsoft.com/en-us/library/windows/desktop/ms681385(v=vs.85).aspx - WinErrCode = map[uint32]SystemError{ + WinErrCode = map[int]SystemError{ 5: SystemError{ Title: "ERROR_ACCESS_DENIED", Description: "Access denied.", From b586567edecb950a2139a16360fd5635fcbc9b26 Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Sat, 17 Mar 2018 12:28:43 +0700 Subject: [PATCH 5/6] contributers --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ae90c48..0ddd43a 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,7 @@ See `examples/cron/cron_job.go` - [0X8C - Demired](https://github.com/Demired) - [Maximus](https://github.com/maximus12793) - [AlgorathDev](https://github.com/AlgorathDev) +- [Alexis Camilleri](https://github.com/krysennn) All the contributors are welcome. If you would like to be the contributor please accept some rules. From 904cd1783434462657a71734e797c773bc9f7f14 Mon Sep 17 00:00:00 2001 From: Igor Dolzhikov Date: Sat, 17 Mar 2018 12:29:07 +0700 Subject: [PATCH 6/6] Bumped version number to 0.10.3 --- daemon.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/daemon.go b/daemon.go index ba0d996..cb62b0d 100644 --- a/daemon.go +++ b/daemon.go @@ -3,7 +3,7 @@ // license that can be found in the LICENSE file. /* -Package daemon 0.10.2 for use with Go (golang) services. +Package daemon 0.10.3 for use with Go (golang) services. Package daemon provides primitives for daemonization of golang services. This package is not provide implementation of user daemon,