Skip to content

proposal: x/sys/windows/svc/mgr: New function to list the service statuses as well as names #62500

@ryharri

Description

@ryharri

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

No one assigned

    Type

    No type

    Projects

    Status

    Incoming

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions