mirror of
https://github.com/rwinkhart/sys.git
synced 2026-09-05 08:37:31 -04:00
windows/svc: allow querying service start reason
The QueryServiceDynamicInformation API makes it possible to determine why a service started. This is declared as an optional function because the API is Win8+. Reference: https://docs.microsoft.com/en-us/windows/win32/api/winsvc/nf-winsvc-queryservicedynamicinformation Change-Id: I18e9a95b35f8c37d94c9900626c1785f425701dc Reviewed-on: https://go-review.googlesource.com/c/sys/+/358394 Trust: Jason A. Donenfeld <Jason@zx2c4.com> Run-TryBot: Jason A. Donenfeld <Jason@zx2c4.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
+25
-1
@@ -80,6 +80,17 @@ type Status struct {
|
||||
ServiceSpecificExitCode uint32 // set if the service has exited with a service-specific exit code
|
||||
}
|
||||
|
||||
// StartReason is the reason that the service was started.
|
||||
type StartReason uint32
|
||||
|
||||
const (
|
||||
StartReasonDemand = StartReason(windows.SERVICE_START_REASON_DEMAND)
|
||||
StartReasonAuto = StartReason(windows.SERVICE_START_REASON_AUTO)
|
||||
StartReasonTrigger = StartReason(windows.SERVICE_START_REASON_TRIGGER)
|
||||
StartReasonRestartOnFailure = StartReason(windows.SERVICE_START_REASON_RESTART_ON_FAILURE)
|
||||
StartReasonDelayedAuto = StartReason(windows.SERVICE_START_REASON_DELAYEDAUTO)
|
||||
)
|
||||
|
||||
// ChangeRequest is sent to the service Handler to request service status change.
|
||||
type ChangeRequest struct {
|
||||
Cmd Cmd
|
||||
@@ -284,7 +295,20 @@ func Run(name string, handler Handler) error {
|
||||
|
||||
// StatusHandle returns service status handle. It is safe to call this function
|
||||
// from inside the Handler.Execute because then it is guaranteed to be set.
|
||||
// This code will have to change once multiple services are possible per process.
|
||||
func StatusHandle() windows.Handle {
|
||||
return theService.h
|
||||
}
|
||||
|
||||
// DynamicStartReason returns the reason why the service was started. It is safe
|
||||
// to call this function from inside the Handler.Execute because then it is
|
||||
// guaranteed to be set.
|
||||
func DynamicStartReason() (StartReason, error) {
|
||||
var allocReason *uint32
|
||||
err := windows.QueryServiceDynamicInformation(theService.h, windows.SERVICE_DYNAMIC_INFORMATION_LEVEL_START_REASON, unsafe.Pointer(&allocReason))
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
reason := StartReason(*allocReason)
|
||||
windows.LocalFree(windows.Handle(unsafe.Pointer(allocReason)))
|
||||
return reason, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user