服务启动
若要启动服务或驱动程序服务,服务控制程序使用 StartService 函数。 如果数据库已锁定, StartService 函数将失败。 如果发生这种情况,服务控制程序应等待几秒钟,然后再次调用 StartService 。 它可以通过调用 QueryServiceLockStatus 函数检查数据库的当前锁状态。
如果服务控制程序正在启动服务,则可以使用 StartService 函数指定要传递给服务的 ServiceMain 函数的参数数组。 创建新线程以执行 ServiceMain 函数后,StartService 函数返回。 服务控制程序可以通过调用 QueryServiceStatus 函数在SERVICE_STATUS结构中检索新启动的服务的状态。 在初始化期间,应SERVICE_START_PENDING dwCurrentState 成员。 dwWaitHint 成员是一个时间间隔(以毫秒为单位),指示服务控制程序在再次调用 QueryServiceStatus 之前应等待多长时间。 初始化完成后,服务会将 dwCurrentState 更改为 SERVICE_RUNNING。
服务控制管理器不支持在启动时将自定义环境变量传递给服务。 此外,当服务正在运行时,服务控制管理器不会检测和传递对环境变量的更改。 不要使服务依赖于环境变量,而是使用注册表值或 ServiceMain 参数。
下面是服务控制管理器启动典型服务时所发生情况的简化概述:
- SCM 从注册表中读取服务路径,并准备启动该服务。 这包括获取服务锁。 在保留服务锁时启动另一个服务的任何尝试都会被阻止,直到释放服务锁。
- SCM 启动进程,并等待子进程退出 (指示) 失败或报告SERVICE_RUNNING状态。
- 应用程序执行其非常简单的初始化并调用 StartServiceCtrlDispatcher 函数。
- StartServiceCtrlDispatcher 连接到服务控制管理器,并启动第二个线程,该线程为服务调用 ServiceMain 函数。 ServiceMain 应尽快报告SERVICE_RUNNING。
- 当服务控制管理器收到服务正在运行的通知时,它会释放服务锁。
如果服务在 80 秒内未更新其状态,加上最后一个等待提示,则服务控制管理器将确定服务已停止响应。 服务控制管理器将记录事件并停止服务。
如果程序正在启动驱动程序服务, 则 StartService 将在设备驱动程序完成初始化后返回。
有关详细信息,请参阅 启动服务。