Win32 服务类

来源:互联网 发布:怎么看金十数据k 编辑:程序博客网 时间:2024/05/20 15:42

由于程序要做成服务,所以自己写了通用服务类,以备忘

XService.h

#pragma onceclass CXService{protected:LPTSTR m_lpServiceName;SERVICE_STATUS_HANDLE m_hServiceStatusHandle;     SERVICE_STATUS m_ServiceStatus; void XServiceHandler(DWORD fdwControl);void XServiceMain(DWORD dwArgc, LPTSTR *lpszArgv);BOOL ReportStatus( DWORD dwCurrentState, DWORD dwWaitHint = 3000, DWORD dwErrExit = 0);public:CXService(LPCTSTR lpServiceName);~CXService();LPCTSTR GetServiceName() { return m_lpServiceName; }static CXService* m_pGlobalHandler;static DWORD Install(LPCTSTR lpServiceName, LPCTSTR lpServiceDiaplayName, LPCTSTR lpBinFilePath);static DWORD Unistall(LPCTSTR lpServiceName);static DWORD Stop(LPCTSTR lpServiceName);static DWORD Start(LPCTSTR lpServiceName);static void WINAPI ServiceHandler(DWORD fdwControl){if(m_pGlobalHandler){m_pGlobalHandler->XServiceHandler(fdwControl);}}static void WINAPI ServiceMain(DWORD dwArgc, LPTSTR *lpszArgv){if(m_pGlobalHandler){m_pGlobalHandler->XServiceMain(dwArgc, lpszArgv);}}void Main();    // Only call this function on mainvirtual DWORD InitService() { return 0; };virtual void Do() = 0;virtual void ShutDown() = 0;};

XService.cpp

#include "stdafx.h"#include "XService.h"CXService* CXService::m_pGlobalHandler = NULL;CXService::CXService(LPCTSTR lpServiceName){if(lstrlen(lpServiceName) > 0){m_lpServiceName = new TCHAR[lstrlen(lpServiceName) + 1];lstrcpy(m_lpServiceName, lpServiceName);}else{m_lpServiceName = NULL;}m_pGlobalHandler = this;}CXService::~CXService(){if(m_lpServiceName){delete []m_lpServiceName;}m_pGlobalHandler = NULL;}DWORD CXService::Install(LPCTSTR lpServiceName, LPCTSTR lpServiceDiaplayName, LPCTSTR lpBinFilePath){SC_HANDLE schSCManager = NULL, schService = NULL;do {schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE); if(NULL == schSCManager) break;schService = CreateService( schSCManager,/* SCManager database      */ lpServiceName,/* name of service         */ lpServiceName,/* service name to display */ SERVICE_ALL_ACCESS,        /* desired access          */ SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS , /* service type            */ SERVICE_AUTO_START,      /* start type              */ SERVICE_ERROR_NORMAL,      /* error control type      */ lpBinFilePath,/* service's binary        */ NULL,                      /* no load ordering group  */ NULL,                      /* no tag identifier       */ NULL,                      /* no dependencies         */ NULL,                      /* LocalSystem account     */ NULL);                     /* no password             */ if(schService == NULL) break;if(lpServiceDiaplayName){SERVICE_DESCRIPTION ServiceDesc; if(lstrlen(lpServiceDiaplayName) > 0){LPTSTR lpBuffer = new TCHAR[lstrlen(lpServiceDiaplayName) + 1];lstrcpy(lpBuffer, lpServiceDiaplayName);ServiceDesc.lpDescription = lpBuffer;     ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &ServiceDesc); delete []lpBuffer;}}CloseServiceHandle(schService);} while (0);if(schSCManager){CloseServiceHandle(schSCManager);}return GetLastError();}DWORD CXService::Unistall(LPCTSTR lpServiceName){SC_HANDLE schSCManager = NULL, schService = NULL;do {schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(schSCManager == NULL) break;schService = OpenService( schSCManager, lpServiceName, SERVICE_ALL_ACCESS);if(schService == NULL) break;DeleteService(schService);CloseServiceHandle(schService);} while (0);if(schSCManager){CloseServiceHandle(schSCManager);}return GetLastError();}DWORD CXService::Stop(LPCTSTR lpServiceName){SC_HANDLE schSCManager = NULL, schService = NULL;do {schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(schSCManager == NULL) break;schService = OpenService( schSCManager, lpServiceName, SERVICE_ALL_ACCESS);if(schService == NULL) break;SERVICE_STATUS status;ControlService(schService,SERVICE_CONTROL_STOP,&status);CloseServiceHandle(schService);} while (0);if(schSCManager){CloseServiceHandle(schSCManager);}return GetLastError();}DWORD CXService::Start(LPCTSTR lpServiceName){SC_HANDLE schSCManager = NULL, schService = NULL;do {schSCManager = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS); if(schSCManager == NULL) break;schService = OpenService( schSCManager, lpServiceName, SERVICE_ALL_ACCESS);if(schService == NULL) break;StartService(schService, 0, (LPCTSTR*)NULL);CloseServiceHandle(schService);} while (0);if(schSCManager){CloseServiceHandle(schSCManager);}return GetLastError();}void CXService::Main(){m_hServiceStatusHandle = NULL;m_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;m_ServiceStatus.dwWin32ExitCode = 0;m_ServiceStatus.dwServiceSpecificExitCode = 0;m_ServiceStatus.dwCheckPoint = 0;m_ServiceStatus.dwWaitHint = 0;if(InitService() == 0){SERVICE_TABLE_ENTRYlpServiceStartTable[] = {{ m_lpServiceName, ServiceMain },{NULL, NULL}};if(!StartServiceCtrlDispatcher(lpServiceStartTable)){}}}BOOL CXService::ReportStatus( DWORD dwCurrentState, DWORD dwWaitHint, DWORD dwErrExit){BOOL fResult = TRUE;if( dwCurrentState == SERVICE_START_PENDING)m_ServiceStatus.dwControlsAccepted = 0;else{//m_ServiceStatus.dwControlsAccepted = m_dwControlsAccepted;}m_ServiceStatus.dwCurrentState = dwCurrentState;m_ServiceStatus.dwWin32ExitCode = NO_ERROR;m_ServiceStatus.dwWaitHint = dwWaitHint;//!! TCW MOD START - added code to support error exitingm_ServiceStatus.dwServiceSpecificExitCode = dwErrExit;if (dwErrExit!=0)m_ServiceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;//!! TCW MOD END - added code to support error exitingif( dwCurrentState == SERVICE_RUNNING ||dwCurrentState == SERVICE_STOPPED )m_ServiceStatus.dwCheckPoint = 0;else{//m_ServiceStatus.dwCheckPoint = ++m_dwCheckPoint;}// Report the status of the service to the service control manager.if (!(fResult = SetServiceStatus( m_hServiceStatusHandle, &m_ServiceStatus))) {}return fResult;}void CXService::XServiceMain(DWORD dwArgc, LPTSTR *lpszArgv){DWORD   status = 0;     DWORD   specificError = 0xfffffff;     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_hServiceStatusHandle = RegisterServiceCtrlHandler(m_lpServiceName, ServiceHandler);     if (m_hServiceStatusHandle == 0)     {    } else{m_ServiceStatus.dwWin32ExitCode = S_OK;m_ServiceStatus.dwCheckPoint = 0;m_ServiceStatus.dwWaitHint = 0;m_ServiceStatus.dwCurrentState = SERVICE_RUNNING;        SetServiceStatus(m_hServiceStatusHandle, &m_ServiceStatus);Do();m_ServiceStatus.dwCurrentState = SERVICE_STOPPED;        SetServiceStatus(m_hServiceStatusHandle, &m_ServiceStatus);}}void CXService::XServiceHandler(DWORD fdwControl){switch(fdwControl) {case SERVICE_CONTROL_STOP:case SERVICE_CONTROL_SHUTDOWN:m_ServiceStatus.dwWin32ExitCode = 0; m_ServiceStatus.dwCurrentState  = SERVICE_STOPPED; m_ServiceStatus.dwCheckPoint    = 0; m_ServiceStatus.dwWaitHint      = 0;ShutDown();break; case SERVICE_CONTROL_PAUSE:m_ServiceStatus.dwCurrentState = SERVICE_PAUSED; break;case SERVICE_CONTROL_CONTINUE:m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; break;case SERVICE_CONTROL_INTERROGATE:break;};    if (!SetServiceStatus(m_hServiceStatusHandle,  &m_ServiceStatus)) {     } }
使用起来很简单

#define SERVICE_NAME _T("TestService")class CMyService : public CXService{public:CMyService() : CXService(SERVICE_NAME){}void Do(){//这里做你真正要做的事情}void ShutDown(){}};int _tmain(int argc, _TCHAR* argv[]){if(argc > 1){if(lstrcmpi(argv[1],_T("-i") ) == 0){TCHAR szBuf[MAX_PATH];GetModuleFileName(NULL, szBuf, MAX_PATH - 1);CXService::Install(SERVICE_NAME, SERVICE_NAME, szBuf);}else if(lstrcmpi(argv[1],_T("-u") ) == 0){CXService::Unistall(SERVICE_NAME);}else if(lstrcmpi(argv[1],_T("-s") ) == 0){CXService::Stop(SERVICE_NAME);}else if(lstrcmpi(argv[1],_T("-r") ) == 0){CXService::Start(SERVICE_NAME);}}else{CMyService m;m.Main();}return 0;}

完成,至此这个服务程序完成了安装,卸载等常用功能。

原创粉丝点击