NotifyServiceStatusChangeA 函数 (winsvc.h)
使应用程序能够在创建或删除指定服务时或状态更改时接收通知。
语法
DWORD NotifyServiceStatusChangeA(
[in] SC_HANDLE hService,
[in] DWORD dwNotifyMask,
[in] PSERVICE_NOTIFYA pNotifyBuffer
);
参数
[in] hService
服务或服务控制管理器的句柄。 OpenService 或 CreateService 函数返回服务的句柄,并且必须具有SERVICE_QUERY_STATUS访问权限。 服务控制管理器的句柄由 OpenSCManager 函数返回,并且必须具有SC_MANAGER_ENUMERATE_SERVICE访问权限。 有关详细信息,请参阅 服务安全和访问权限。
每个服务只能有一个未完成的通知请求。
[in] dwNotifyMask
应报告的状态更改类型。 此参数可以是以下一个或多个值。
价值 | 意义 |
---|---|
|
创建服务时进行报告。
hService 参数必须是 SCM 的句柄。 |
|
服务即将继续时进行报告。
hService 参数必须是服务的句柄。 |
|
在调用 DeleteService 函数时报告应用程序何时指定了服务。 应用程序应关闭服务的任何句柄,以便将其删除。
hService 参数必须是服务的句柄。 |
|
报告服务已删除时间。 如果应用程序具有服务的打开句柄,则无法接收此通知。
hService 参数必须是 SCM 的句柄。 |
|
服务暂停时报告。
hService 参数必须是服务的句柄。 |
|
服务暂停时报告。
hService 参数必须是服务的句柄。 |
|
报告服务运行时。
hService 参数必须是服务的句柄。 |
|
服务启动时报告。
hService 参数必须是服务的句柄。 |
|
报告服务何时停止。
hService 参数必须是服务的句柄。 |
|
报告服务已停止时。
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,则可能会出现内存泄漏。
注意
winsvc.h 标头将 NotifyServiceStatusChange 定义为一个别名,该别名根据 UNICODE 预处理器常量的定义自动选择此函数的 ANSI 或 Unicode 版本。 将中性编码别名与不中性编码的代码混合使用可能会导致编译或运行时错误不匹配。 有关详细信息,请参阅函数原型的
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows Vista [仅限桌面应用] |
支持的最低服务器 | Windows Server 2008 [仅限桌面应用] |
目标平台 | 窗户 |
标头 | winsvc.h (包括 Windows.h) |
库 | Advapi32.lib |
DLL | Advapi32.dll |