服务触发器事件

发生触发器事件时,服务可以注册为启动或停止。 这样就无需服务在系统启动时启动,也无需服务轮询或主动等待事件;服务可以在需要时启动,而不是自动启动,无论是否有工作要做。 预定义触发器事件的示例包括指定设备接口类的设备到达或特定防火墙端口的可用性。 服务还可以注册由 Windows 事件跟踪 (ETW) 提供程序生成的自定义触发器事件。

Windows Server 2008、Windows Vista、Windows Server 2003 和 Windows XP: 在 Windows Server 2008 R2 和 Windows 7 之前,不支持服务触发器事件。

触发器由触发器事件类型、触发器事件子类型、响应触发器事件所要执行的操作以及某些触发器事件类型的 (组成,) 一个或多个特定于触发器的数据项。 子类型和触发器特定的数据项共同指定向服务通知事件的条件。 数据项的格式取决于触发器事件类型;数据项可以是二进制数据、字符串或多字符串。 字符串必须是 Unicode;不支持 ANSI 字符串。

为了注册触发器事件,该服务使用 SERVICE_CONFIG_TRIGGER_INFO 调用 ChangeServiceConfig2 并提供SERVICE_TRIGGER_INFO结构。 SERVICE_TRIGGER_INFO 结构指向SERVICE_TRIGGER结构的数组,每个结构指定一个触发器。

如果系统启动时触发条件为 true,或者当系统运行时触发条件为 true,则执行指定的触发器操作。 例如,如果服务注册为在特定设备可用时启动,则当设备已插入计算机时,将在系统启动时启动该服务;如果用户在系统运行时插入设备,则服务会在设备到达时启动。

如果触发器具有特定于触发器的数据项,则仅当触发器事件附带的数据项与服务使用触发器指定的数据项之一匹配时,才会执行触发器操作。 二进制数据匹配是通过按位比较完成的。 字符串匹配不区分大小写。 如果数据项是多字符串,则多字符串中的所有字符串都必须匹配。

当服务启动以响应触发器事件时,服务在其 ServiceMain 回调函数中接收 argv[1] SERVICE_TRIGGER_STARTED_ARGUMENTArgv[0] 始终是服务的短名称。

注册为在响应触发器事件时启动的服务可能会在空闲超时后停止自身,而服务无法执行任何操作。 停止自身的服务必须准备好处理在服务停止自身时到达 SERVICE_CONTROL_TRIGGEREVENT 控制请求。 每当服务处于运行状态时发生新的触发器事件时,SCM 就会发送 SERVICE_CONTROL_TRIGGEREVENT 控制请求。 为了避免丢失触发器事件,服务应返回 ERROR_SHUTDOWN_IN_PROGRESS 服务从运行过渡到停止时到达的任何 SERVICE_CONTROL_TRIGGEREVENT 控制请求。 这会指示 SCM 将触发事件排队,并等待服务进入停止状态。 然后,SCM 执行与排队触发器事件关联的操作,例如启动服务。

当服务准备好再次处理触发器事件时,它会在调用 SetServiceStatus 时在其控件接受的掩码中设置SERVICE_ACCEPT_TRIGGEREVENT。 这通常在服务使用 SERVICE_RUNNING 调用 SetServiceStatus 时完成。 然后,SCM 会为每个排队的触发器事件发出 SERVICE_CONTROL_TRIGGEREVENT 请求,直到队列为空。

无法停止运行有依赖服务的服务以响应触发器事件。

在内存不足的情况下,无法保证触发-启动和触发器-停止请求。

使用 QueryServiceConfig2 函数检索服务的触发器事件配置。

SC 工具 (sc.exe) 可用于在命令提示符下配置或查询服务的触发器事件。 使用 triggerinfo 选项将服务配置为启动或停止以响应触发器事件。 使用 qtriggerinfo 选项查询服务的触发器配置。

以下示例查询 W32time 服务的触发器配置,该服务配置为在计算机加入域时启动,并在计算机离开域时停止。

C:\>sc qtriggerinfo w32time
[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: w32time

        START SERVICE
          DOMAIN JOINED STATUS         : 1ce20aba-9851-4421-9430-1ddeb766e809 [DOMAIN JOINED]
        STOP SERVICE
          DOMAIN JOINED STATUS         : ddaf516e-58c2-4866-9574-c3b615d42ea1 [NOT DOMAIN JOINED]

以下示例查询平板电脑输入服务的触发器配置,该服务配置为在 具有 GUID {4d1e55b2-f16f-11cf-88cb-0011111000030} 且任何指定的 HID 设备 ID 到达时启动。

C:\>sc qtriggerinfo tabletinputservice
[SC] QueryServiceConfig2 SUCCESS

SERVICE_NAME: tabletinputservice

        START SERVICE
          DEVICE INTERFACE ARRIVAL     : 4d1e55b2-f16f-11cf-88cb-001111000030 [INTERFACE CLASS GUID]
            DATA                       : HID_DEVICE_UP:000D_U:0001
            DATA                       : HID_DEVICE_UP:000D_U:0002
            DATA                       : HID_DEVICE_UP:000D_U:0003
            DATA                       : HID_DEVICE_UP:000D_U:0004