SetServiceStatus 函数 (winsvc.h)

汇报调用服务的服务控制管理器的状态信息。

语法

BOOL SetServiceStatus(
  [in] SERVICE_STATUS_HANDLE hServiceStatus,
  [in] LPSERVICE_STATUS      lpServiceStatus
);

参数

[in] hServiceStatus

当前服务的状态信息结构的句柄。 此句柄由 RegisterServiceCtrlHandlerEx 函数返回。

[in] lpServiceStatus

指向 SERVICE_STATUS 结构的指针包含调用服务的最新状态信息。

返回值

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

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

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

返回代码 说明
ERROR_INVALID_DATA
指定的服务状态结构无效。
ERROR_INVALID_HANDLE
指定的句柄无效。

注解

ServiceMain 函数首先调用 RegisterServiceCtrlHandlerEx 函数以获取服务的SERVICE_STATUS_HANDLE。 然后,它会立即调用 SetServiceStatus 函数,以通知服务控制管理器其状态为SERVICE_START_PENDING。 在初始化期间,服务可以提供更新的状态,以指示它正在取得进展,但它需要更多的时间。 一个常见的 bug 是服务让main线程执行初始化,而单独的线程继续调用 SetServiceStatus 以防止服务控制管理器将其标记为挂起。 但是,如果main线程挂起,则服务启动会以无限循环结束,因为工作线程继续报告main线程正在取得进展。

处理控制请求后,如果服务状态发生更改,则服务的 Handler 函数必须调用 SetServiceStatus ,以便向服务控制管理器报告其新状态。 仅在服务正在更改状态时(例如,在处理停止或关闭控件时)时才需要这样做。 服务还可以随时从服务的任何线程使用此函数,以通知服务控制管理器状态更改,例如,服务何时必须因可恢复错误而停止。

服务只有在调用 RegisterServiceCtrlHandlerEx 以获取服务状态句柄后,才能调用此函数。

如果服务调用 SetServiceStatusdwCurrentState 成员设置为 SERVICE_STOPPED, 而 dwWin32ExitCode 成员设置为非零值,则会将以下条目写入系统事件日志:

   Event ID    = 7023
   Source      = Service Control Manager
   Type        = Error
   Description = <ServiceName> terminated with the following error:
                 <ExitCode>.

以下是调用此函数时的最佳做法:

  • 初始化SERVICE_STATUS结构中的所有字段,确保挂起状态具有有效的检查点和等待提示值。 使用合理的等待提示。
  • 当状态为SERVICE_START_PENDING或服务可能会崩溃时,请勿注册以接受控件。 初始化完成后,接受SERVICE_CONTROL_STOP代码。
  • 仅当服务在与挂起的启动、停止、暂停或继续操作相关的任务上取得进展时,才使用检查点和等待提示值调用此函数。 否则,SCM 无法检测服务是否挂起。
  • 如果 ServiceMain 失败,请使用相应的退出代码输入停止状态。
  • 如果状态为SERVICE_STOPPED,请执行所有必要的清理,并仅调用 一次 SetServiceStatus 。 此函数对 SCM 进行 LRPC 调用。 第一次调用处于SERVICE_STOPPED状态的函数将关闭 RPC 上下文句柄,任何后续调用都可能导致进程崩溃。
  • 使用 SERVICE_STOPPED 调用 SetServiceStatus 后,请勿尝试执行任何其他工作,因为服务进程可以随时终止。

示例

有关示例,请参阅 编写 ServiceMain 函数

要求

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

另请参阅

HandlerEx

RegisterServiceCtrlHandlerEx

SERVICE_STATUS

服务函数

ServiceMain

SetServiceBits