NT指的是電腦作業系統的核心,有NT4.0/server2000/xp/server2003/vista/2008.是微軟NT系列NT伺服器網路是電腦網路中伺服器是NT型主機。
一個NT服務有三部分構成:
1:Service Control Manager(SCM) 每個WIN NT/2K都有一個SCM,他存在於Service.exe中.
2:服務本身一個服務擁有能從SCM受到訊號和命令所必需的特殊代碼,並能夠在處理後將他的狀態返回SCM.
3:Service Control Dispatcher(SCP) 他是一個擁有使用者截面,允許使用者開始,暫停,繼續,並且控制已經安裝在電腦上作為服務啟動並執行WIN32
下面我們來見實踐NT服務的架構,編寫一個完整的NT服務。
#include <stdio.h>#include <windows.h>SERVICE_STATUS m_ServiceStatus;SERVICE_STATUS_HANDLE m_ServiceStatusHandle;BOOL bRunning=true;void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);//服務主函數void WINAPI ServiceCtrlHandler(DWORD Opcode);//服務控制函數void WINAPI CmdStart(void);//要啟動的程式函數BOOL InstallService(); //安裝服務的函數BOOL DeleteService(); //刪除服務的函數int main(int argc, char* argv[]){printf("\twindows based service demo\n");printf("\tgxisone@hotmail.com\n"); if(argc!=3){printf("usage: %s -install[remove]",argv[0]);return 0;}if(strcmp(argv[1],"-install")==0) /// install{if(InstallService())printf("\n\nService Installed Sucessfully\n");elseprintf("\n\nError Installing Service\n");}else if(strcmp(argv[1],"-remove")==0) // remove{if(DeleteService())printf("\n\nService remove sucessfully\n");elseprintf("\n\nError removing Service\n");} else{printf("\nusage: %s -install[remove]\n",argv[0]);return 0;}//在進入點函數裡面要完成ServiceMain的初始化,//準確點說是初始化一個SERVICE_TABLE_ENTRY結構數組,//這個結構記錄了這個服務程式裡面所包含的所有服務的名稱//和服務的進入點函數SERVICE_TABLE_ENTRY DispatchTable[]={{"WindowsMgr",ServiceMain},{NULL,NULL}};//最後的NULL指明數組的結束 StartServiceCtrlDispatcher(DispatchTable); return 0;}void WINAPI ServiceMain(DWORD argc, LPTSTR *argv){m_ServiceStatus.dwServiceType = SERVICE_WIN32;m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;m_ServiceStatus.dwWin32ExitCode = 0; m_ServiceStatus.dwServiceSpecificExitCode = 0; m_ServiceStatus.dwCheckPoint = 0; m_ServiceStatus.dwWaitHint = 0;m_ServiceStatusHandle = RegisterServiceCtrlHandler("WindowsMgr",ServiceCtrlHandler);if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)return; m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //設定服務狀態m_ServiceStatus.dwCheckPoint = 0; m_ServiceStatus.dwWaitHint = 0; //SERVICE_STATUS結構含有七個成員,它們反映服務的現行狀態。//所有這些成員必須在這個結構被傳遞到SetServiceStatus之前正確的設定SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus); bRunning=true;//* CmdStart(); //啟動我們的服務程式//*return; }void WINAPI ServiceCtrlHandler(DWORD Opcode)//服務控制函數{switch(Opcode) { case SERVICE_CONTROL_PAUSE: // we accept the command to pause itm_ServiceStatus.dwCurrentState = SERVICE_PAUSED; break; case SERVICE_CONTROL_CONTINUE: // we got the command to continuem_ServiceStatus.dwCurrentState = SERVICE_RUNNING; break; case SERVICE_CONTROL_STOP: // we got the command to stop this servicem_ServiceStatus.dwWin32ExitCode = 0; m_ServiceStatus.dwCurrentState = SERVICE_STOPPED; m_ServiceStatus.dwCheckPoint = 0; m_ServiceStatus.dwWaitHint = 0; SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);bRunning=false;break;case SERVICE_CONTROL_INTERROGATE: // break; } return; }BOOL InstallService() //安裝服務函數{char strDir[1024];SC_HANDLE schSCManager,schService;GetCurrentDirectory(1024,strDir);GetModuleFileName(NULL,strDir,sizeof(strDir));char chSysPath[1024];GetSystemDirectory(chSysPath,sizeof(chSysPath));strcat(chSysPath,"\\WindowsMgr.exe");if(!CopyFile(strDir,chSysPath,FALSE))printf("Copy file OK\n"); // 把我們的服務程式複製到系統根目錄strcpy(strDir,chSysPath);schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); if (schSCManager == NULL) {printf("open scmanger failed,maybe you do not have the privilage to do this\n");return false;}LPCTSTR lpszBinaryPathName=strDir;schService = CreateService(schSCManager,"WindowsMgr","Windows Manger Control", //將服務的資訊添加到SCM的資料庫SERVICE_ALL_ACCESS, // desired access SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type lpszBinaryPathName, // service's binary NULL, // no load ordering group NULL, // no tag identifier NULL, // no dependencies NULL, // LocalSystem account NULL); // no password if (schService == NULL) {printf("faint,we failed just because we invoke createservices failed\n");return false; }CloseServiceHandle(schService); return true;}BOOL DeleteService(){SC_HANDLE schSCManager;SC_HANDLE hService;schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); char chSysPath[1024];GetSystemDirectory(chSysPath,sizeof(chSysPath)); strcat(chSysPath,"\\WindowsMgr.exe");if (schSCManager == NULL) {printf("faint,open scmanger failed\n");return false; }hService=OpenService(schSCManager,"WindowsMgr",SERVICE_ALL_ACCESS);if (hService == NULL) {printf("faint,open services failt\n");return false;} if(DeleteFile(chSysPath)==0){printf("Dell file Failure !\n"); return false;}else printf("Delete file OK!\n");if(DeleteService(hService)==0)return false; if(CloseServiceHandle(hService)==0)return false;elsereturn true;}void WINAPI CmdStart(void){//--------------------------------//把你的要做成服務啟動的程式碼添加到這裡//那麼你的代碼就可以作為NT服務啟動了//--------------------------------}