Platform SDK: DLLs, Processes, and Threads |
The ControlService function sends a control code to a service.
BOOL ControlService( SC_HANDLE hService, // handle to service DWORD dwControl, // control code LPSERVICE_STATUS lpServiceStatus // status information );
Control code | Meaning |
---|---|
SERVICE_CONTROL_STOP | Requests the service to stop. The hService handle must have SERVICE_STOP access. |
SERVICE_CONTROL_PAUSE | Requests the service to pause. The hService handle must have SERVICE_PAUSE_CONTINUE access. |
SERVICE_CONTROL_CONTINUE | Requests the paused service to resume. The hService handle must have SERVICE_PAUSE_CONTINUE access. |
SERVICE_CONTROL_INTERROGATE | Requests the service to update immediately its current status information to the service control manager. The hService handle must have SERVICE_INTERROGATE access. |
SERVICE_CONTROL_PARAMCHANGE | Windows 2000: Requests the service to reread its startup parameters. The hService handle must have SERVICE_PAUSE_CONTINUE access. |
SERVICE_CONTROL_NETBINDCHANGE | Windows 2000: Requests the service to update its network binding. The hService handle must have SERVICE_PAUSE_CONTINUE access. |
This value can also be a user-defined control code, as described in the following table.
Control code | Meaning |
---|---|
Range 128 to 255. | The service defines the action associated with the control code. The hService handle must have SERVICE_USER_DEFINED_CONTROL access. |
The service control manager fills in the structure only when ControlService returns one of the following error codes: NO_ERROR, ERROR_INVALID_SERVICE_CONTROL, ERROR_SERVICE_CANNOT_ACCEPT_CTRL, or ERROR_SERVICE_NOT_ACTIVE. Otherwise, the structure is not filled in.
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
The following error codes can be set by the service control manager. Other error codes can be set by the registry functions that are called by the service control manager.
Error code | Meaning |
---|---|
ERROR_ACCESS_DENIED | The specified handle was not opened with the necessary access. |
ERROR_DEPENDENT_SERVICES_RUNNING | The service cannot be stopped because other running services are dependent on it. |
ERROR_INVALID_HANDLE | The specified handle was not obtained using CreateService or OpenService, or the handle is no longer valid. |
ERROR_INVALID_PARAMETER | The requested control code is undefined. |
ERROR_INVALID_SERVICE_CONTROL | The requested control code is not valid, or it is unacceptable to the service. |
ERROR_SERVICE_CANNOT_ACCEPT_CTRL | The requested control code cannot be sent to the service because the state of the service is SERVICE_STOPPED, SERVICE_START_PENDING, or SERVICE_STOP_PENDING. |
ERROR_SERVICE_NOT_ACTIVE | The service has not been started. |
ERROR_SERVICE_REQUEST_TIMEOUT | The process for the service was started, but it did not call StartServiceCtrlDispatcher, or the thread that called StartServiceCtrlDispatcher may be blocked in a control handler function. |
ERROR_SHUTDOWN_IN_PROGRESS | The system is shutting down. |
The ControlService function asks the service control manager to send the requested control code to the service. The service control manager sends the code if the service accepts the control and if the service is in a state in which a control can be sent to it. You cannot stop and start a service unless the security descriptor allows you to. The default security descriptor allows LocalSystem, Administrators, and Power Users to stop and start services. To change the security descriptor of a service, use SetServiceObjectSecurity.
The QueryServiceStatus or function returns a SERVICE_STATUS structure whose dwCurrentState and dwControlsAccepted members indicate the current state and controls accepted by a running service. All running services accept the SERVICE_CONTROL_INTERROGATE control code by default. Drivers do not accept control codes other than SERVICE_CONTROL_STOP and SERVICE_CONTROL_INTERROGATE. Each service specifies the other control codes that it accepts when it calls the SetServiceStatus function to report its status. A service should always accept these codes when it is running, no matter what it is doing.
The following table shows the action of the service control manager in each of the possible service states.
Service state | Stop | Other controls |
---|---|---|
STOPPED | (c) | (c) |
STOP_PENDING | (b) | (b) |
START_PENDING | (a) | (b) |
RUNNING | (a) | (a) |
CONTINUE_PENDING | (a) | (a) |
PAUSE_PENDING | (a) | (a) |
PAUSED | (a) | (a) |
(a) | If the service accepts this control code, send the request to the service; otherwise, ControlService returns zero and GetLastError returns ERROR_INVALID_SERVICE_CONTROL. | |
(b) | The service is not in a state in which a control can be sent to it, so ControlService returns zero and GetLastError returns ERROR_SERVICE_CANNOT_ACCEPT_CTRL. | |
(c) | The service is not active, so ControlService returns zero and GetLastError returns ERROR_SERVICE_NOT_ACTIVE. |
Windows NT/2000: Requires Windows NT 3.1 or later.
Header: Declared in Winsvc.h; include Windows.h.
Library: Use Advapi32.lib.
Services Overview, Service Functions, CreateService, OpenService, QueryServiceStatus, SetServiceObjectSecurity, SetServiceStatus, SERVICE_STATUS