VC 后台服务程序

最近准备把以前写的一个对时程序改成服务类型的,学习了一下服务程序的写法:

 

已知Bug:

   1.服务安装完成后,不会马上自动启动,需要重启电脑,服务才会自动启动。

   2.删除服务后,需要重启电脑才会从服务管理器里面移除.这个可以操作注册表修正

   3.停止服务时,总会提示1053的错误,但服务还是会停止

 

新建一Win32控制台程序:

 

1.全局声明:

  1. #include <windows.h>  
  2. #include <stdio.h>  
  3. #define IDS_APPNAME     "DNetTimeSrv"   //应用程序名  
  4. #define IDS_SERVICENAME "DNetTimeSrv"   //服务名称  
  5. #define IDS_SERVICEDESC "DOS synchronize service"   //服务描述  
  6. void InstallService();  //安装服务  
  7. void UnInstallService();    //删除服务  
  8. void WINAPI ServiceMain_DNetTime(DWORD dwArgc,LPTSTR *lpArgv);  //服务处理主函数,注册服务  
  9. void WINAPI ServiceCtrlHandle(DWORD dwCtrlCode);    //服务控制,注册服务时用  
  10. void LogEvent(WORD wType,LPCTSTR lpszText); //事件记录  
  11. LPCTSTR GetErrMsg(DWORD dwCode);  
  12. BOOL ServiceControl(DWORD dwControlID);  
  13. BOOL ServiceStart();  
  14. void DNetTimeSrvProc(); //服务执行体,写想要做的事  
  15. SERVICE_STATUS g_ServiceStatus; //记录服务状态  
  16. SERVICE_STATUS_HANDLE g_hServiceStatus; //注册服务时返回值,服务控制时用  
  17. BOOL g_bService;    //一个标记,退出执行体用.可以换成事件  

2.服务程序主函数:

     主要功能:安装/删除服务,服务控制事件分派

  1. int main(int argc,char* argv[])  
  2. {  
  3.     if(argc == 2 && (*(argv[1]) == '-' || *(argv[1]) == '/'))  
  4.     {  
  5.         if(stricmp(argv[1]+1,"Install") == 0)  
  6.         {  
  7.             InstallService();  
  8.         }  
  9.         else if(stricmp(argv[1]+1,"UnInstall") == 0)  
  10.         {  
  11.             UnInstallService();  
  12.         }  
  13.         else if(stricmp(argv[1]+1,"Start") == 0)  
  14.         {  
  15.             ServiceStart();  
  16.         }  
  17.         else  
  18.         {  
  19.             goto Dispatch;  //如果这里不跳转,在启动时会提示1053,无法启动;也可以把参数这一节另外写一个程序  
  20.         }  
  21.         return 0;  
  22.     }  
  23. Dispatch:  
  24.     SERVICE_TABLE_ENTRY ste[] =  
  25.     {  
  26.         {TEXT(IDS_SERVICENAME),ServiceMain_DNetTime}, //服务名,服务处理主函数  
  27.         {NULL,NULL} //最后必须有一个NULL  
  28.     };  
  29.     if(!StartServiceCtrlDispatcher(ste)) //服务事件分派  
  30.     {  
  31.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  32.         return -1;  
  33.     }  
  34.     return 0;  
  35. }  

3.服务安装函数:

  1. void InstallService()  
  2. {  
  3.     char szPath[255] = {0};  
  4.     GetModuleFileName(NULL,szPath,255);  
  5.     SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);  
  6.     if(hSCM == NULL)  
  7.     {  
  8.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  9.         return;  
  10.     }  
  11.     SC_HANDLE hService = CreateService(hSCM,TEXT(IDS_SERVICENAME),TEXT(IDS_SERVICENAME),  
  12.                                        SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,  
  13.                                        SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,szPath,  
  14.                                        NULL,NULL,NULL,NULL,NULL);  
  15.     if(hService == NULL)  
  16.     {  
  17.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  18.         CloseServiceHandle(hSCM);  
  19.         return;  
  20.     }  
  21.     SERVICE_DESCRIPTION sd;  
  22.     sd.lpDescription = TEXT(IDS_SERVICEDESC);  
  23.         //添加服务描述信息  
  24.     ::ChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sd);  
  25.     LogEvent(EVENTLOG_INFORMATION_TYPE,TEXT("Install service successed"));  
  26.     CloseServiceHandle(hService);  
  27.     CloseServiceHandle(hSCM);  
  28.     printf("Install service successed!/r/n");  
  29. }  

4.服务删除函数:

  1. void UnInstallService()  
  2. {  
  3.     SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);  
  4.     if(NULL == hSCM)  
  5.     {  
  6.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  7.         return;  
  8.     }  
  9.     SC_HANDLE hService = OpenService(hSCM,TEXT(IDS_SERVICENAME),SERVICE_STOP | DELETE);  
  10.     if(NULL == hService)  
  11.     {  
  12.         printf("Open service error!/r/n");  
  13.         printf(TEXT(GetErrMsg(GetLastError())));  
  14.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  15.         CloseServiceHandle(hSCM);  
  16.         return;  
  17.     }  
  18.     QueryServiceStatus(hService,&g_ServiceStatus);  
  19.     if(g_ServiceStatus.dwCurrentState == SERVICE_RUNNING)  
  20.     {  
  21.         if(!ControlService(hService,SERVICE_CONTROL_STOP,&g_ServiceStatus))  
  22.         {  
  23.             printf("control service error!/r/n");  
  24.             printf(TEXT(GetErrMsg(GetLastError())));  
  25.             LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  26.             CloseServiceHandle(hService);  
  27.             CloseServiceHandle(hSCM);  
  28.             return;  
  29.         }  
  30.     }  
  31.       
  32.     if(!DeleteService(hService))  
  33.     {  
  34.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  35.     }  
  36.     else  
  37.     {  
  38.         printf("Uninstall successed!/r/n");  
  39.     }  
  40.     CloseServiceHandle(hService);  
  41.     CloseServiceHandle(hSCM);  
  42. }  

5.服务处理主函数:

    主要功能:注册服务,启动服务,循环服务执行体函数.

  1. void WINAPI ServiceMain_DNetTime(DWORD dwArgc,LPTSTR *lpArgv)  
  2. {  
  3.     g_ServiceStatus.dwCheckPoint = 0;  
  4.     g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;  
  5.     g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;  
  6.     g_ServiceStatus.dwServiceSpecificExitCode = 0;  
  7.     g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;  
  8.     g_ServiceStatus.dwWaitHint = 0;  
  9.     g_ServiceStatus.dwWin32ExitCode = 0;  
  10.         //注册服务  
  11.     g_hServiceStatus = RegisterServiceCtrlHandler(TEXT(IDS_SERVICENAME),ServiceCtrlHandle);  
  12.     if(g_hServiceStatus == 0)  
  13.     {  
  14.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  15.         return;  
  16.     }  
  17.     //g_ServiceStatus.dwWaitHint = 3000;  
  18.     //SetServiceStatus(g_hServiceStatus,&g_ServiceStatus);  
  19.     g_ServiceStatus.dwWaitHint = 0;  
  20.     g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;  
  21.     SetServiceStatus(g_hServiceStatus,&g_ServiceStatus);  
  22.     g_bService = true;  
  23.     //if(!ServiceStart()) return;  
  24.         //服务实现  
  25.     while (g_bService)  
  26.     {  
  27.         DNetTimeSrvProc();  
  28.     }  
  29. }  

6.服务控制函数:

    主要功能:控制服务运行状态:启动/停止/暂停/恢复

  1. void WINAPI ServiceCtrlHandle(DWORD dwCtrlCode)  
  2. {  
  3.     switch(dwCtrlCode)  
  4.     {  
  5.     case SERVICE_CONTROL_CONTINUE:  
  6.         g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;  
  7.         break;  
  8.     case SERVICE_CONTROL_PAUSE:  
  9.         g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;  
  10.         break;  
  11.     case SERVICE_CONTROL_STOP:  
  12.         g_ServiceStatus.dwCheckPoint = 0;  
  13.         g_ServiceStatus.dwWaitHint = 0;  
  14.         g_ServiceStatus.dwWin32ExitCode = 0;  
  15.         g_bService = false;  
  16.         g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;  
  17.         break;  
  18.     default:  
  19.         break;  
  20.     }  
  21.     ServiceControl(dwCtrlCode); //不要这句也可以  
  22.     if(!SetServiceStatus(g_hServiceStatus,&g_ServiceStatus))  
  23.     {  
  24.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  25.     }  
  26. }  

7.服务执行体函数:

    主要功能:服务的功能实现

  1. void DNetTimeSrvProc()  
  2. {  
  3.     HANDLE hFile = CreateFile("c://testap//test.dat",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,  
  4.                               NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);  
  5.     if(hFile == INVALID_HANDLE_VALUE)  
  6.     {  
  7.         LogEvent(EVENTLOG_ERROR_TYPE,GetErrMsg(GetLastError()));  
  8.         return;  
  9.     }  
  10.       
  11.     SYSTEMTIME st;  
  12.     GetSystemTime(&st);  
  13.     char cText[20];  
  14.     sprintf(cText,"%04d-%02d-%02d %02d:%02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);  
  15.     DWORD dwSize = 20;  
  16.     WriteFile(hFile,cText,dwSize,&dwSize,NULL);  
  17.     CloseHandle(hFile);  
  18.     Sleep(1000);  
  19.       
  20. }  

8.其它函数:

    主要功能:服务程序的一些不怎么重要的东东

  1. BOOL ServiceStart()  
  2. //这个功能没用上  
  3.     SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);  
  4.     if(NULL == hSCM)  
  5.     {  
  6.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  7.         return false;  
  8.     }  
  9.     SC_HANDLE hService = OpenService(hSCM,TEXT(IDS_SERVICENAME),SERVICE_ALL_ACCESS);  
  10.     if(NULL == hService)  
  11.     {  
  12.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  13.         CloseServiceHandle(hSCM);  
  14.         return false;  
  15.     }  
  16.     if(!StartService(hService,0,NULL))  
  17.     {  
  18.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  19.         return false;  
  20.     }  
  21.     LogEvent(EVENTLOG_INFORMATION_TYPE,TEXT("Service Started"));  
  22.     return true;  
  23. }  
  24. BOOL ServiceControl(DWORD dwControlID)  
  25. {  
  26.     SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);  
  27.     if(NULL == hSCM)  
  28.     {  
  29.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  30.         return false;  
  31.     }  
  32.     SC_HANDLE hService = OpenService(hSCM,TEXT(IDS_SERVICENAME),SERVICE_STOP | SERVICE_RUNNING | SERVICE_PAUSED);  
  33.     if(NULL == hService)  
  34.     {  
  35.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  36.         CloseServiceHandle(hSCM);  
  37.         return false;  
  38.     }  
  39.     if(!ControlService(hService,dwControlID,&g_ServiceStatus))  
  40.     {  
  41.         LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));  
  42.         CloseServiceHandle(hService);  
  43.         CloseServiceHandle(hSCM);  
  44.         return false;  
  45.     }  
  46.     CloseServiceHandle(hService);  
  47.     CloseServiceHandle(hSCM);  
  48.     return true;  
  49. }  
  50. void LogEvent(WORD wType,LPCTSTR lpszText)  
  51. {  
  52.     HANDLE hLogSouce = RegisterEventSource(NULL,TEXT(IDS_APPNAME));  
  53.     if(hLogSouce == NULL)  
  54.     {  
  55.         return;  
  56.     }  
  57.     ReportEvent(hLogSouce,wType,0,GetLastError(),NULL,1,0,&lpszText,NULL);  
  58.     DeregisterEventSource(hLogSouce);  
  59. }  
  60. LPCTSTR GetErrMsg(DWORD dwCode)  
  61. {  
  62.     LPVOID lpBuf;  
  63.     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,  
  64.                   0,dwCode,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPSTR)&lpBuf,0,NULL);  
  65.     return (LPCTSTR)lpBuf;  

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值