StartServiceCtrlDispatcherA 函数 (winsvc.h)

将服务进程的main线程连接到服务控制管理器,这会使线程成为调用进程的服务控制调度程序线程。

语法

BOOL StartServiceCtrlDispatcherA(
  [in] const SERVICE_TABLE_ENTRYA *lpServiceStartTable
);

参数

[in] lpServiceStartTable

指向 SERVICE_TABLE_ENTRY 结构的数组的指针,其中包含可在调用过程中执行的每个服务的一个条目。 表中最后一个条目的成员必须具有 NULL 值才能指定表的末尾。

返回值

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

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

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

返回代码 说明
ERROR_FAILED_SERVICE_CONTROLLER_CONNECT
如果程序以控制台应用程序而不是服务的形式运行,则返回此错误。

如果程序将作为控制台应用程序运行以用于调试目的,请对其进行构造,以便在返回此错误时不调用特定于服务的代码。

ERROR_INVALID_DATA
指定的调度表包含格式不当的条目。
ERROR_SERVICE_ALREADY_RUNNING
该过程已调用 StartServiceCtrlDispatcher。 每个进程只能调用 StartServiceCtrlDispatcher 一次。

注解

当服务控制管理器启动服务进程时,它会等待进程调用 StartServiceCtrlDispatcher 函数。 服务进程的main线程应在) 30 秒内启动 (后尽快进行此调用。 如果 StartServiceCtrlDispatcher 成功,它将调用线程连接到服务控制管理器,并且不会返回,直到进程中的所有正在运行的服务都进入SERVICE_STOPPED状态。 服务控制管理器使用此连接将控制和服务启动请求发送到服务进程的main线程。 main线程充当调度程序,方法是调用相应的 HandlerEx 函数来处理控制请求,或者在启动新服务时创建新线程以执行相应的 ServiceMain 函数。

lpServiceTable 参数包含可在调用过程中运行的每个服务的条目。 每个条目指定该服务的 ServiceMain 函数。 对于SERVICE_WIN32_SHARE_PROCESS服务,每个条目都必须包含服务的名称。 此名称是安装服务时 由 CreateService 函数指定的服务名称。 对于SERVICE_WIN32_OWN_PROCESS服务,将忽略表条目中的服务名称。

如果服务在其自己的进程中运行,则服务进程的main线程应立即调用 StartServiceCtrlDispatcher。 启动服务时,所有初始化任务都在服务的 ServiceMain 函数中完成。

如果多个服务共享一个进程,并且需要在调用任何 ServiceMain 函数之前完成一些常见的进程范围的初始化,则main线程可以在调用 StartServiceCtrlDispatcher 之前执行该工作,只要花费的时间少于 30 秒。 否则,必须创建另一个线程来执行进程范围的初始化,而main线程调用 StartServiceCtrlDispatcher 并成为服务控制调度程序。 任何特定于服务的初始化仍应在单个服务main函数中完成。

服务不应尝试直接显示用户界面。 有关详细信息,请参阅 Interactive Services

示例

有关示例,请参阅 编写服务程序的 Main 函数

注意

winsvc.h 标头将 StartServiceCtrlDispatcher 定义为别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将非特定编码别名的使用与非非特定编码的代码混合使用可能会导致不匹配,从而导致编译或运行时错误。 有关详细信息,请参阅 函数原型的约定

要求

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

另请参阅

ControlService

HandlerEx

SERVICE_TABLE_ENTRY

服务入口点

服务函数

ServiceMain