用VC++建立Service服務(wù)應(yīng)用程序
作者:李佳穎(niying)
本文主要介紹了OpenSCManager、CreateService、OpenService、ControlService、DeleteService、RegisterServiceCtrlHandler、SetServiceStatus、StartServiceCtrlDispatcher等操作服務(wù)程序的主要幾個(gè)API的用法,具體的函數(shù)參數(shù)大家可以查閱MSDN。
為什么要使用服務(wù)應(yīng)該程序呢?服務(wù)程序就像系統(tǒng)的一些服務(wù)一樣,能夠自動(dòng)地啟動(dòng),并執(zhí)行相應(yīng)的操作;而且因?yàn)榉?wù)程序的在層次上和一般的應(yīng)用程序不同,其能夠在系統(tǒng)啟動(dòng)時(shí)就自動(dòng)地運(yùn)行,而不像一般的應(yīng)用程序那樣一定要在登陸后才能運(yùn)行,這些就是服務(wù)的一些好處了,如果你也想你的程序具有這樣的功能,那么你就可以建立一個(gè)服務(wù)應(yīng)用程序了。下面就跟著我一步一步地教你怎么去創(chuàng)建一個(gè)服務(wù)應(yīng)用程序吧。
一、建立 Win32 Application 應(yīng)用程序(當(dāng)然你也可以建立其它的應(yīng)用程序,但服務(wù)一般是沒(méi)有用戶界面的),并命名為 ServiceTest。
二、定義全局函數(shù)變量。這里主要是設(shè)置服務(wù)句柄和狀態(tài)。
BOOL IsInstalled();BOOL Install();BOOL Uninstall();void LogEvent(LPCTSTR pszFormat, ...);void WINAPI ServiceMain();void WINAPI ServiceStrl(DWORD dwOpcode);TCHAR szServiceName[] = _T("ServiceTest");BOOL bInstall;SERVICE_STATUS_HANDLE hServiceStatus;SERVICE_STATUS status;DWORD dwThreadID;三、添加Init初始化函數(shù)。
void Init(){hServiceStatus = NULL;status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;status.dwCurrentState = SERVICE_STOPPED;tatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;status.dwWin32ExitCode = 0;status.dwServiceSpecificExitCode = 0;status.dwCheckPoint = 0;status.dwWaitHint = 0;}四、添加安裝和刪除服務(wù)函數(shù)。這里主要是用到了四個(gè)函數(shù) OpenSCManager 和 CreateService。OpenSCManager用于打開(kāi)服務(wù)控制管理器;CreateService用于創(chuàng)建服務(wù);OpenService用于打開(kāi)已有的服務(wù),返回該服務(wù)的句柄;ControlService則用于控制已打開(kāi)的服務(wù)狀態(tài),這里是讓服務(wù)停止后才刪除;DeleteService 用于刪除指定服務(wù)。
BOOL Install();{//這里列出主要的兩個(gè)函數(shù),其它的可以在代碼里找。//打開(kāi)服務(wù)控制管理器OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//創(chuàng)建服務(wù)SC_HANDLE hService = ::CreateService(hSCM, szServiceName, szServiceName,SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL,szFilePath, NULL, NULL, _T(""), NULL, NULL);::CloseServiceHandle(hService);::CloseServiceHandle(hSCM);}五、添加服務(wù)主線程函數(shù)和控制函數(shù)。這里調(diào)用 RegisterServiceCtrlHandler 來(lái)注冊(cè)服務(wù)的控制函數(shù),這里要設(shè)置status.dwControlsAccepted 為 SERVICE_ACCEPT_STOP,否則你不能控制這個(gè)服務(wù)的狀態(tài)。
BOOL Uninstall();{//這里列出主要的兩個(gè)函數(shù),其它的可以在代碼里找。//打開(kāi)服務(wù)控制管理器OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);//打開(kāi)服務(wù)OpenService(hSCM, szServiceName, SERVICE_STOP | DELETE);//停止服務(wù)ControlService(hService, SERVICE_CONTROL_STOP, &status);//刪除服務(wù)DeleteService(hService);…}
void WINAPI ServiceMain(){// Register the control request handlerstatus.dwCurrentState = SERVICE_START_PENDING;status.dwControlsAccepted = SERVICE_ACCEPT_STOP;//這個(gè)要使用,否則你不能控制//注冊(cè)服務(wù)控制hServiceStatus = RegisterServiceCtrlHandler(szServiceName, ServiceStrl);if (hServiceStatus == NULL){LogEvent(_T("Handler not installed"));return;}SetServiceStatus(hServiceStatus, &status);status.dwWin32ExitCode = S_OK;status.dwCheckPoint = 0;status.dwWaitHint = 0;status.dwCurrentState = SERVICE_RUNNING;SetServiceStatus(hServiceStatus, &status);//模擬服務(wù)的運(yùn)行,10后自動(dòng)退出。應(yīng)用時(shí)將主要任務(wù)放于此即可int i = 0;while (i < 10){Sleep(1000);i++;}//status.dwCurrentState = SERVICE_STOPPED;SetServiceStatus(hServiceStatus, &status);LogEvent(_T("Service stopped"));}六、在主線程函數(shù)里注冊(cè)控制函數(shù)和程序執(zhí)行主體。這里主要是說(shuō)明這就是程序的執(zhí)行體。
void WINAPI ServiceMain(){…//模擬服務(wù)的運(yùn)行,10后自動(dòng)退出。應(yīng)用時(shí)將主要任務(wù)放于此即可int i = 0;while (i < 10){Sleep(1000);i++;}…}七、最后,要在main函數(shù)里注冊(cè)添加安裝、刪除、注冊(cè)主函數(shù)。
int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){Init();dwThreadID = ::GetCurrentThreadId();SERVICE_TABLE_ENTRY st[] ={{ szServiceName, (LPSERVICE_MAIN_FUNCTION)ServiceMain },{ NULL, NULL }};if (stricmp(lpCmdLine, "/install") == 0){Install();}else if (stricmp(lpCmdLine, "/uninstall") == 0){Uninstall();}else{if (!::StartServiceCtrlDispatcher(st)){LogEvent(_T("Register Service Main Function Error!"));}}return 0;}八、總結(jié)。其實(shí)做一個(gè)服務(wù)程序并不難,主要是懂得程序的執(zhí)行體放于哪里?和注冊(cè)程序的主函數(shù)和注冊(cè)控制函數(shù),如果這兩個(gè)沒(méi)有注冊(cè)的話,你就程序就不知道如何去控制了。status.dwControlsAccepted =SERVICE_ACCEPT_STOP;這個(gè)也重要,如果你沒(méi)有設(shè)置的話,那么服務(wù)就不會(huì)受你控制了。
聯(lián)系客服