-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Open
Labels
Milestone
Description
We have a use case where we want to connect to a remote windows server and list all of the services on it, along with their running status.
In x/sys/windows/svc/mgr, ListServices() returns all of the services that exist, and then we have to loop through them calling Query() to get the state. This doesn't perform well, so instead, I've got my own custom function in my code which returns the status along with the service name. It looks like this:
type nameAndState struct {
name string
state int
}
func getServices(m *mgr.Mgr) ([]nameAndState, error) {
var err error
var bytesNeeded, servicesReturned uint32
var buf []byte
for {
var p *byte
if len(buf) > 0 {
p = &buf[0]
}
err = windows.EnumServicesStatusEx(m.Handle, windows.SC_ENUM_PROCESS_INFO,
windows.SERVICE_WIN32, windows.SERVICE_STATE_ALL,
p, uint32(len(buf)), &bytesNeeded, &servicesReturned, nil, nil)
if err == nil {
break
}
if err != syscall.ERROR_MORE_DATA {
return nil, err
}
if bytesNeeded <= uint32(len(buf)) {
return nil, err
}
buf = make([]byte, bytesNeeded)
}
if servicesReturned == 0 {
return nil, nil
}
services := (*[1 << 20]windows.ENUM_SERVICE_STATUS_PROCESS)(unsafe.Pointer(&buf[0]))[:servicesReturned]
var n []nameAndState
for _, s := range services {
name := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(s.ServiceName))[:])
n = append(n, nameAndState{name: name, state: int(s.ServiceStatusProcess.CurrentState)})
}
return n, nil
}It would be good if this functionality was included in the standard mgr package though. It would have to be a new function for backwards compatibility but it could potentially even return the whole ENUM_SERVICE_STATUS_PROCESS struct as an array to expose everything.
Metadata
Metadata
Assignees
Labels
Type
Projects
Status
Incoming