一般情況下,我們都使用一個(gè)單獨(dú)的exe來(lái)承載自己的服務(wù),但是可以觀察下系統(tǒng)的svchost.exe進(jìn)程,可以看到,系統(tǒng)利用svchost一個(gè)進(jìn)程,承載了多個(gè)服務(wù),每個(gè)服務(wù)都使用了dll來(lái)實(shí)現(xiàn)。
這篇文章詳細(xì)描述了如何使用系統(tǒng)的svchost來(lái)承載我們自己的服務(wù)《創(chuàng)建SvcHost.exe調(diào)用的服務(wù)原理與實(shí)踐》,雖然這是篇2003年寫(xiě)的老文章,但是里面的實(shí)現(xiàn)方式到現(xiàn)在仍然是可用的。
這里針對(duì)自己實(shí)現(xiàn)過(guò)程的經(jīng)驗(yàn),再做一些補(bǔ)充:
- dll的導(dǎo)出函數(shù)不一定得是ServiceMain,也可以是自己定義的名稱,只要在注冊(cè)表中HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ServiceMain這個(gè)值里寫(xiě)上即可
- 注冊(cè)的控制命令回調(diào)函數(shù)ServiceCtrlHandler是運(yùn)行在另一個(gè)線程,不和ServieMain同個(gè)線程;
- ServiceCtrlHandler盡量不要做復(fù)雜且耗時(shí)的事情,不然scm會(huì)認(rèn)為服務(wù)沒(méi)有響應(yīng)了
- ServiceCtrlHandler響應(yīng)SERVICE_CONTROL_STOP命令時(shí),最好先向scm標(biāo)記狀態(tài)為SERVICE_STOP_PENDING,同時(shí)給出一個(gè)建議的等待時(shí)間,好讓ServiceMain能感知這個(gè)停止請(qǐng)求,并做好清理工作以正常退出
- 一旦向scm標(biāo)記狀態(tài)為SERVICE_STOPPED,后續(xù)的代碼都不會(huì)被運(yùn)行,因?yàn)閐ll立馬就會(huì)被卸載