ControlService 函数 (winsvc.h)

将控制代码发送到服务。

若要在停止服务时指定其他信息,请使用 ControlServiceEx 函数。

语法

BOOL ControlService(
  [in]  SC_HANDLE        hService,
  [in]  DWORD            dwControl,
  [out] LPSERVICE_STATUS lpServiceStatus
);

参数

[in] hService

服务的句柄。 此句柄由 OpenServiceCreateService 函数返回。 此句柄所需的 访问权限 取决于请求的 dwControl 代码。

[in] dwControl

此参数可以是以下控制代码之一。

控制代码 含义
SERVICE_CONTROL_CONTINUE
0x00000003
通知暂停的服务应恢复。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。
SERVICE_CONTROL_INTERROGATE
0x00000004
通知服务它应将其当前状态信息报告给服务控制管理器。 hService 句柄必须具有SERVICE_INTERROGATE访问权限。

请注意,此控件通常并不有用,因为 SCM 知道服务的当前状态。

SERVICE_CONTROL_NETBINDADD
0x00000007
通知网络服务有用于绑定的新组件。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。 但是,此控制代码已弃用;请改用即插即用功能。
SERVICE_CONTROL_NETBINDDISABLE
0x0000000A
通知网络服务其其中一个绑定已被禁用。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。 但是,此控制代码已弃用;请改用即插即用功能。
SERVICE_CONTROL_NETBINDENABLE
0x00000009
通知网络服务已启用禁用的绑定。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。 但是,此控制代码已弃用;请改用即插即用功能。
SERVICE_CONTROL_NETBINDREMOVE
0x00000008
通知网络服务已删除用于绑定的组件。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。 但是,此控制代码已弃用;请改用即插即用功能。
SERVICE_CONTROL_PARAMCHANGE
0x00000006
通知服务其启动参数已更改。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。
SERVICE_CONTROL_PAUSE
0x00000002
通知服务它应暂停。 hService 句柄必须具有SERVICE_PAUSE_CONTINUE访问权限。
SERVICE_CONTROL_STOP
0x00000001
通知服务它应停止。 hService 句柄必须具有SERVICE_STOP访问权限。

将停止请求发送到服务后,不应向服务发送其他控件。

 

此值也可以是用户定义的控件代码,如下表所述。

控制代码 含义
范围 128 到 255
服务定义与控件代码关联的操作。 hService 句柄必须具有SERVICE_USER_DEFINED_CONTROL访问权限。

[out] lpServiceStatus

指向接收最新服务状态信息的 SERVICE_STATUS 结构的指针。 返回的信息反映了服务向服务控制管理器报告的最新状态。

仅当 GetLastError 返回以下错误代码之一时,服务控制管理器才会填充结构: NO_ERRORERROR_INVALID_SERVICE_CONTROLERROR_SERVICE_CANNOT_ACCEPT_CTRLERROR_SERVICE_NOT_ACTIVE。 否则,不会填充结构。

返回值

如果该函数成功,则返回值为非零值。

如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。

服务控制管理器可以设置以下错误代码。 其他错误代码可由服务控制管理器调用的注册表函数设置。

返回代码 说明
ERROR_ACCESS_DENIED
句柄没有所需的访问权限。
ERROR_DEPENDENT_SERVICES_RUNNING
无法停止该服务,因为其他正在运行的服务都依赖于它。
ERROR_INVALID_HANDLE
未使用 CreateServiceOpenService 获取指定的句柄,或者该句柄不再有效。
ERROR_INVALID_PARAMETER
请求的控制代码未定义。
ERROR_INVALID_SERVICE_CONTROL
请求的控制代码无效或服务无法接受该控制代码。
ERROR_SERVICE_CANNOT_ACCEPT_CTRL
无法将请求的控制代码发送到服务,因为服务的状态为 SERVICE_STOPPEDSERVICE_START_PENDINGSERVICE_STOP_PENDING
ERROR_SERVICE_NOT_ACTIVE
该服务尚未启动。
ERROR_SERVICE_REQUEST_TIMEOUT
服务的进程已启动,但它未调用 StartServiceCtrlDispatcher,或者调用 StartServiceCtrlDispatcher 的线程可能会在控件处理程序函数中被阻止。
ERROR_SHUTDOWN_IN_PROGRESS
系统正在关闭。

注解

ControlService 函数要求服务控制管理器 (SCM) 将请求的控制代码发送到服务。 如果服务已指定它将接受代码,并且处于可向其发送控制代码的状态,则 SCM 会发送代码。

SCM 以串行方式处理服务控制通知,它将等待一个服务完成服务控制通知的处理,然后再发送下一个服务控制通知。 因此,如果任何服务忙于处理控件代码,则对 ControlService 的调用将阻止 30 秒。 如果在超时过期时忙服务仍未从其处理程序函数返回, 则 ControlService 将失败并 ERROR_SERVICE_REQUEST_TIMEOUT

若要停止和启动服务,需要一个允许执行此操作的安全描述符。 默认安全描述符允许 LocalSystem 帐户以及管理员组和 Power Users 组的成员停止和启动服务。 若要更改服务的安全描述符,请参阅 修改服务的 DACL

QueryServiceStatusEx 函数返回一个SERVICE_STATUS_PROCESS结构,其 dwCurrentStatedwControlsAccepted 成员指示正在运行的服务接受的当前状态和控件。 默认情况下,所有正在运行的服务都接受 SERVICE_CONTROL_INTERROGATE 控制代码。 驱动程序不接受 除SERVICE_CONTROL_STOPSERVICE_CONTROL_INTERROGATE以外的控制代码。 每个服务指定它在调用 SetServiceStatus 函数以报告其状态时接受的其他控制代码。 服务在运行时应始终接受这些代码,无论它正在执行什么操作。

下表显示了 SCM 在每个可能的服务状态中的操作。

服务状态 停止 其他控件
STOPPED (c) (c)
STOP_PENDING (b) (b)
START_PENDING () (b)
运行 () ()
CONTINUE_PENDING () ()
PAUSE_PENDING () ()
暂停 () ()
()
如果服务接受此控制代码,请将请求发送到服务;否则, ControlService 返回零, GetLastError 返回 ERROR_INVALID_SERVICE_CONTROL
(b)
服务不处于可向其发送控件的状态,因此 ControlService 返回零, GetLastError 返回 ERROR_SERVICE_CANNOT_ACCEPT_CTRL
(c)
服务未处于活动状态,因此 ControlService 返回零, GetLastError 返回 ERROR_SERVICE_NOT_ACTIVE

示例

有关示例,请参阅 停止服务

要求

要求
最低受支持的客户端 Windows XP [仅限桌面应用]
最低受支持的服务器 Windows Server 2003 [仅限桌面应用]
目标平台 Windows
标头 winsvc.h (包括 Windows.h)
Library AdvApi32.lib
DLL AdvApi32.dll

另请参阅

ControlServiceEx

CreateService

OpenService

QueryServiceStatusEx

SERVICE_STATUS

服务控制请求

服务函数

SetServiceObjectSecurity

SetServiceStatus