資源描述:
《快速編寫簡單windows服務程序》由會員上傳分享,免費在線閱讀,更多相關內(nèi)容在工程資料-天天文庫。
1、前不久,為完成項目中某個功能,需要寫個windows服務程序,定時來調(diào)用另外的一個exe程序,完成過程遇到頗多問題,作為初學者,分享一下我的整個過程.參考了多位大神的文章.資料來自網(wǎng)上,最后給出鏈接.表示感謝以下是一些基本知識,不得不耐下心去理解,這對程序理解和編寫非常用幫助.首先Microsoft?Windows服務(即,以前的?NT服務)使您能夠創(chuàng)建在它們自己的Windows會話中可長時間運行的可執(zhí)行應用程序。這些服務可以在計算機啟動時自動啟動,可以暫停和重新啟動而且不顯示任何用戶界面。這使服務非常適合在服務器上使用,或任何時候,為了不影響在同一臺計算機上工作
2、的其他用戶,需要長時間運行功能時使用。還可以在不同于登錄用戶的特定用戶帳戶或默認計算機帳戶的安全上下文中運行服務。?服務是有狀態(tài)的,當我們使用windows自帶的服務管理程序sc.exe查看服務狀態(tài)時可以顯示服務的當前狀態(tài),這個狀態(tài)是由我們在程序代碼中進行控制的。你最好在服務初始化的時候將服務設置為SERVICE_START_PENDING,當初始化完畢時設為SERVICE_RUNNING,這些狀態(tài)是系統(tǒng)自定義的狀態(tài),可通過msdn查看其他狀態(tài)。這個狀態(tài)信息你會在sc.exe中看到。?在編寫windows服務程序過程中你需要關注的函數(shù)有:?1.首先是main函數(shù),
3、由于windows服務不需要界面,所以大部分程序為win32控制臺應用程序,所以程序主函數(shù)為main而不是WinMain()。在主函數(shù)要做的主要工作就是初始化一個SERVICE_TABLE_ENTRY分派表結構體,然后調(diào)用StartServiceCtrlDispatcher();這將把調(diào)用進程的主線程轉換為控制分派器。該分派器啟動一個新線程,該線程運行分派表中對應于你的服務的ServiceMain()函數(shù)。ServiceMain()函數(shù)將在下面提到。?此過程示例代碼如下:?SERVICE_TABLE_ENTRYentrytable[2];???entrytable
4、[0].lpServiceName="testservice";???entrytable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;???entrytable[1].lpServiceName=NULL;???entrytable[1].lpServiceProc=NULL;?StartServiceCtrlDispatcher(entrytable);?在這之后系統(tǒng)將自動創(chuàng)建一個線程去執(zhí)行ServiceMain函數(shù)的內(nèi)容,你應該將你要執(zhí)行的任務在ServiceMain中循環(huán),這樣服務就開始運行了
5、。?2.ServiceMain函數(shù)為voidWINAPIServiceMain(intargc,char**argv)格式的函數(shù),函數(shù)名字可以任意定義。它的作用就是:將你需要執(zhí)行的任務放到該函數(shù)中循環(huán)執(zhí)行即可。這就是服務程序的工作函數(shù)。在ServiceMain執(zhí)行你的任務前,需要給SERVICE_TABLE_ENTRY分派表結構體進行賦值,注意由于此時服務還沒有開始執(zhí)行你的任務所以我們將服務的狀態(tài)設置為SERVICE_START_PENDING,即正在初始化。我們進行如下賦值:?servicestatus.dwServiceType=SERVICE_WIN32;?
6、??servicestatus.dwCurrentState=SERVICE_START_PENDING;?servicestatus.dwControlsAccepted=SERVICE_ACCEPT_SHUTDOWN
7、SERVICE_ACCEPT_STOP;?//在本例中只接受系統(tǒng)關機和停止服務兩種控制命令???servicestatus.dwWin32ExitCode=0;???servicestatus.dwServiceSpecificExitCode=0;???servicestatus.dwCheckPoint=0;???servicestatus.
8、dwWaitHint=0;?hstatus=::RegisterServiceCtrlHandler("testservice",CtrlHandler);?CtrlHandler為voidWINAPICtrlHandler(DWORDrequest)型的函數(shù),函數(shù)名字可以任意設定。將在下一點講到。Hstatus為SERVICE_STATUS_HANDLE類型的全局變量。當需要改變服務狀態(tài)時SetServiceStatus()函數(shù)需要它做為參數(shù)來標識一個服務。?3.voidWINAPICtrlHandler(DWORDrequest),函數(shù)的主要功能是,接收系統(tǒng)傳
9、遞的控制命