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 结构的指针,例如指向回调函数的指针。 在调用回调函数或调用线程取消通知请求之前,此结构必须保持有效。

除非第一次调用的回调函数已完成缓冲区或取消第一个通知请求,否则不要使用同一缓冲区参数对 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之前卸载 DLL,则通知将导致不可预知的结果,并可能导致进程停止响应。
 

注意

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

要求

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

另请参阅

SERVICE_NOTIFY

SubscribeServiceChangeNotifications

Service Functions