一般情况下,我们都使用一个单独的exe来承载自己的服务,但是可以观察下系统的svchost.exe进程,可以看到,系统利用svchost一个进程,承载了多个服务,每个服务都使用了dll来实现。
这篇文章详细描述了如何使用系统的svchost来承载我们自己的服务《创建SvcHost.exe调用的服务原理与实践》,虽然这是篇2003年写的老文章,但是里面的实现方式到现在仍然是可用的。
这里针对自己实现过程的经验,再做一些补充:
- dll的导出函数不一定得是ServiceMain,也可以是自己定义的名称,只要在注册表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceMain这个值里写上即可
- 注册的控制命令回调函数ServiceCtrlHandler是运行在另一个线程,不和ServieMain同个线程;
- ServiceCtrlHandler尽量不要做复杂且耗时的事情,不然scm会认为服务没有响应了
- ServiceCtrlHandler响应SERVICE_CONTROL_STOP命令时,最好先向scm标记状态为SERVICE_STOP_PENDING,同时给出一个建议的等待时间,好让ServiceMain能感知这个停止请求,并做好清理工作以正常退出
- 一旦向scm标记状态为SERVICE_STOPPED,后续的代码都不会被运行,因为dll立马就会被卸载