notifyServiceStatusChangeA 函数 (winsvc.h)

使应用程序能够在创建或删除指定的服务或其状态更改时接收通知。

语法

DWORD NotifyServiceStatusChangeA(
  [in] SC_HANDLE        hService,
  [in] DWORD            dwNotifyMask,
  [in] PSERVICE_NOTIFYA pNotifyBuffer
);

参数

[in] hService

服务或服务控制管理器的句柄。 服务的句柄由 OpenServiceCreateService 函数返回,必须具有SERVICE_QUERY_STATUS访问权限。 服务控制管理器的句柄由 OpenSCManager 函数返回,并且必须具有SC_MANAGER_ENUMERATE_SERVICE访问权限。 有关详细信息,请参阅 服务安全和访问权限

每个服务只能有一个未完成的通知请求。

[in] dwNotifyMask

应报告的状态更改的类型。 此参数可使用以下一个或多个值。

含义
SERVICE_NOTIFY_CREATED
0x00000080
报告服务创建时间。

hService 参数必须是 SCM 的句柄。

SERVICE_NOTIFY_CONTINUE_PENDING
0x00000010
报告服务何时要继续。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_DELETE_PENDING
0x00000200
报告应用程序何时在 对 DeleteService 函数的调用中指定了服务。 应用程序应关闭服务的任何句柄,以便将其删除。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_DELETED
0x00000100
报告删除服务时。 如果应用程序具有服务的打开句柄,则无法接收此通知。

hService 参数必须是 SCM 的句柄。

SERVICE_NOTIFY_PAUSE_PENDING
0x00000020
报告服务何时暂停。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_PAUSED
0x00000040
报告服务暂停时间。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_RUNNING
0x00000008
报告服务何时正在运行。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_START_PENDING
0x00000002
报告服务何时启动。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_STOP_PENDING
0x00000004
报告服务何时停止。

hService 参数必须是服务的句柄。

SERVICE_NOTIFY_STOPPED
0x00000001
报告服务何时停止。

hService 参数必须是服务的句柄。

[in] pNotifyBuffer

指向包含通知信息的 SERVICE_NOTIFY 结构的指针,例如指向回调函数的指针。 在调用回调函数或调用线程取消通知请求之前,此结构必须保持有效。

在第一次调用的回调函数使用缓冲区完成或取消第一个通知请求之前,不要使用相同的 buffer 参数对 NotifyServiceStatusChange 进行多次调用。 否则,无法保证回调函数将接收哪个版本的缓冲区。

Windows Vista: 回调函数的地址必须在已加载模块的地址范围内。 因此,回调函数不能是运行时生成的代码, (如 JIT 编译器) 生成的托管代码或在运行时解压缩的本机代码。 Windows Server 2008 和 Windows Vista SP1 中已删除此限制。

返回值

如果函数成功,则返回值为 ERROR_SUCCESS。 如果服务已标记为要删除,则返回值ERROR_SERVICE_MARKED_FOR_DELETE并且必须关闭该服务的句柄。 如果服务通知滞后于系统状态,该函数将返回ERROR_SERVICE_NOTIFY_CLIENT_LAGGING。 在这种情况下,客户端应关闭 SCM 的句柄,打开一个新句柄,然后再次调用此函数。

如果函数失败,则返回值为 系统错误代码之一。

注解

NotifyServiceStatusChange 函数可用于接收有关服务应用程序的通知。 它不能用于接收有关驱动程序服务的通知。

当服务状态发生更改时,系统会调用指定的回调函数作为异步过程调用, (APC) 排队到调用线程。 调用线程必须输入可警报的等待 (例如,调用 SleepEx 函数) 接收通知。 有关详细信息,请参阅 异步过程调用

如果在调用 NotifyServiceStatusChange 时服务已处于任何请求状态,则回调函数将立即排队。 如果下次使用相同的服务和状态调用函数时服务状态未更改,则回调函数不会立即排队;回调函数在服务下次进入请求的状态时排队。

NotifyServiceStatusChange 函数使用THREAD_SET_CONTEXT访问权限调用调用线程上的 OpenThread 函数。 如果调用线程没有此访问权限, NotifyServiceStatusChange 将失败。 如果调用线程正在模拟其他用户,则它可能没有足够的权限来设置上下文。

从执行等待的线程调用 NotifyServiceStatusChange 比创建其他线程更有效。

调用回调函数后,调用方必须调用 NotifyServiceStatusChange 才能接收其他通知。 请注意,Windows API 中的某些函数(包括 NotifyServiceStatusChange 和其他 SCM 函数)使用远程过程调用 (RPC) ;这些函数可能会执行可发出警报的等待操作,因此无法安全地从回调函数内部调用。 相反,回调函数应保存通知参数,并在回调之外执行任何其他工作。

若要取消未完成的通知,请使用 CloseServiceHandle 函数关闭服务句柄。 CloseServiceHandle 成功后,将不再将通知 APC 排队。 如果调用线程退出时未关闭服务句柄或等待 APC 生成,则可能发生内存泄漏。

重要 如果调用线程位于 DLL 中,并且 DLL 在线程收到通知或调用 CloseServiceHandle 之前卸载,则通知将导致不可预知的结果,并可能导致进程停止响应。
 

注意

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

要求

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

另请参阅

SERVICE_NOTIFY

SubscribeServiceChangeNotifications

服务函数