一般情況下,我們都使用一個單獨的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立馬就會被卸載