服务的ServiceMain函数

本文详细介绍Windows服务编程的基本步骤,包括ServiceMain函数的功能实现、服务状态报告机制及初始化过程中的注意事项等关键技术点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当服务控制程序请求运行新服务时,服务控制管理器(SCM)启动服务并向控制调度程序发送启动请求。 控制调度程序创建一个新线程来执行服务的ServiceMain功能。

ServiceMain函数应执行以下任务:

  1. 初始化所有全局变量。

  2. 立即调用RegisterServiceCtrlHandler函数以注册Handler函数来处理服务的控制请求。RegisterServiceCtrlHandler的返回值是一个服务状态句柄 ,将在调用中用于通知SCM服务状态。

  3. 执行初始化。 如果预期初始化代码的执行时间非常短(小于一秒),则可以直接在ServiceMain中执行初始化。

    如果预计初始化时间超过一秒,则服务应使用以下初始化技术之一:

    • 调用SetServiceStatus函数报告SERVICE_RUNNING,但在初始化完成之前不接受任何控制。 该服务通过在SERVICE_STATUS结构中调用SetServiceStatus并将dwCurrentState设置为SERVICE_RUNNING并将dwControlsAccepted设置为0来执行此操作。 这可确保SCM在服务准备就绪之前不会向服务发送任何控制请求,并释放SCM以管理其他服务。 建议使用这种初始化方法来提高性能,尤其是对于自动启动服务。

    • 报告SERVICE_START_PENDING,不接受任何控件,并指定等待提示。 如果服务的初始化代码执行预期花费的时间超过初始等待提示值的任务,则代码必须定期调用SetServiceStatus函数(可能带有修订的等待提示)以指示正在进行的进度。 确保仅在初始化进行时调用SetServiceStatus 。 否则,SCM可以等待您的服务进入SERVICE_RUNNING状态,假设您的服务正在取得进展并阻止其他服务启动。 除非您确定执行初始化的线程确实正在取得进展,否则不要从单独的线程调用SetServiceStatus 。

      使用此方法的服务还可以指定检查点值,并在冗长的初始化期间定期递增值。 启动该服务的程序可以调用QueryServiceStatusQueryServiceStatusEx以从SCM获取最新的检查点值,并使用该值向用户报告增量进度。

  4. 初始化完成后,调用SetServiceStatus将服务状态设置为SERVICE_RUNNING,并指定服务准备接受的控件。 有关控件列表,请参阅SERVICE_STATUS结构。

  5. 执行服务任务,或者,如果没有挂起的任务,则将控制权返回给调用者。 服务状态的任何更改都需要调用SetServiceStatus来报告新的状态信息。

  6. 如果在服务初始化或运行时发生错误,则服务应调用SetServiceStatus以将服务状态设置为SERVICE_STOP_PENDING(如果清理将很长)。 清理完成后,调用SetServiceStatus将服务状态从最后一个线程设置为SERVICE_STOPPED以终止。 请务必设置SERVICE_STATUS结构的dwServiceSpecificExitCodedwWin32ExitCode成员以识别错误。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

道格拉斯范朋克

播种花生牛奶自留田

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值