最近准备把以前写的一个对时程序改成服务类型的,学习了一下服务程序的写法:
已知Bug:
1.服务安装完成后,不会马上自动启动,需要重启电脑,服务才会自动启动。
2.删除服务后,需要重启电脑才会从服务管理器里面移除.这个可以操作注册表修正
3.停止服务时,总会提示1053的错误,但服务还是会停止
新建一Win32控制台程序:
1.全局声明:
- #include <windows.h>
- #include <stdio.h>
- #define IDS_APPNAME "DNetTimeSrv" //应用程序名
- #define IDS_SERVICENAME "DNetTimeSrv" //服务名称
- #define IDS_SERVICEDESC "DOS synchronize service" //服务描述
- void InstallService(); //安装服务
- void UnInstallService(); //删除服务
- void WINAPI ServiceMain_DNetTime(DWORD dwArgc,LPTSTR *lpArgv); //服务处理主函数,注册服务
- void WINAPI ServiceCtrlHandle(DWORD dwCtrlCode); //服务控制,注册服务时用
- void LogEvent(WORD wType,LPCTSTR lpszText); //事件记录
- LPCTSTR GetErrMsg(DWORD dwCode);
- BOOL ServiceControl(DWORD dwControlID);
- BOOL ServiceStart();
- void DNetTimeSrvProc(); //服务执行体,写想要做的事
- SERVICE_STATUS g_ServiceStatus; //记录服务状态
- SERVICE_STATUS_HANDLE g_hServiceStatus; //注册服务时返回值,服务控制时用
- BOOL g_bService; //一个标记,退出执行体用.可以换成事件
2.服务程序主函数:
主要功能:安装/删除服务,服务控制事件分派
- int main(int argc,char* argv[])
- {
- if(argc == 2 && (*(argv[1]) == '-' || *(argv[1]) == '/'))
- {
- if(stricmp(argv[1]+1,"Install") == 0)
- {
- InstallService();
- }
- else if(stricmp(argv[1]+1,"UnInstall") == 0)
- {
- UnInstallService();
- }
- else if(stricmp(argv[1]+1,"Start") == 0)
- {
- ServiceStart();
- }
- else
- {
- goto Dispatch; //如果这里不跳转,在启动时会提示1053,无法启动;也可以把参数这一节另外写一个程序
- }
- return 0;
- }
- Dispatch:
- SERVICE_TABLE_ENTRY ste[] =
- {
- {TEXT(IDS_SERVICENAME),ServiceMain_DNetTime}, //服务名,服务处理主函数
- {NULL,NULL} //最后必须有一个NULL
- };
- if(!StartServiceCtrlDispatcher(ste)) //服务事件分派
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return -1;
- }
- return 0;
- }
3.服务安装函数:
- void InstallService()
- {
- char szPath[255] = {0};
- GetModuleFileName(NULL,szPath,255);
- SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
- if(hSCM == NULL)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return;
- }
- SC_HANDLE hService = CreateService(hSCM,TEXT(IDS_SERVICENAME),TEXT(IDS_SERVICENAME),
- SERVICE_ALL_ACCESS,SERVICE_WIN32_OWN_PROCESS,
- SERVICE_AUTO_START,SERVICE_ERROR_NORMAL,szPath,
- NULL,NULL,NULL,NULL,NULL);
- if(hService == NULL)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- CloseServiceHandle(hSCM);
- return;
- }
- SERVICE_DESCRIPTION sd;
- sd.lpDescription = TEXT(IDS_SERVICEDESC);
- //添加服务描述信息
- ::ChangeServiceConfig2(hService,SERVICE_CONFIG_DESCRIPTION,&sd);
- LogEvent(EVENTLOG_INFORMATION_TYPE,TEXT("Install service successed"));
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCM);
- printf("Install service successed!/r/n");
- }
4.服务删除函数:
- void UnInstallService()
- {
- SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
- if(NULL == hSCM)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return;
- }
- SC_HANDLE hService = OpenService(hSCM,TEXT(IDS_SERVICENAME),SERVICE_STOP | DELETE);
- if(NULL == hService)
- {
- printf("Open service error!/r/n");
- printf(TEXT(GetErrMsg(GetLastError())));
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- CloseServiceHandle(hSCM);
- return;
- }
- QueryServiceStatus(hService,&g_ServiceStatus);
- if(g_ServiceStatus.dwCurrentState == SERVICE_RUNNING)
- {
- if(!ControlService(hService,SERVICE_CONTROL_STOP,&g_ServiceStatus))
- {
- printf("control service error!/r/n");
- printf(TEXT(GetErrMsg(GetLastError())));
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCM);
- return;
- }
- }
- if(!DeleteService(hService))
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- }
- else
- {
- printf("Uninstall successed!/r/n");
- }
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCM);
- }
5.服务处理主函数:
主要功能:注册服务,启动服务,循环服务执行体函数.
- void WINAPI ServiceMain_DNetTime(DWORD dwArgc,LPTSTR *lpArgv)
- {
- g_ServiceStatus.dwCheckPoint = 0;
- g_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
- g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
- g_ServiceStatus.dwServiceSpecificExitCode = 0;
- g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
- g_ServiceStatus.dwWaitHint = 0;
- g_ServiceStatus.dwWin32ExitCode = 0;
- //注册服务
- g_hServiceStatus = RegisterServiceCtrlHandler(TEXT(IDS_SERVICENAME),ServiceCtrlHandle);
- if(g_hServiceStatus == 0)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return;
- }
- //g_ServiceStatus.dwWaitHint = 3000;
- //SetServiceStatus(g_hServiceStatus,&g_ServiceStatus);
- g_ServiceStatus.dwWaitHint = 0;
- g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
- SetServiceStatus(g_hServiceStatus,&g_ServiceStatus);
- g_bService = true;
- //if(!ServiceStart()) return;
- //服务实现
- while (g_bService)
- {
- DNetTimeSrvProc();
- }
- }
6.服务控制函数:
主要功能:控制服务运行状态:启动/停止/暂停/恢复
- void WINAPI ServiceCtrlHandle(DWORD dwCtrlCode)
- {
- switch(dwCtrlCode)
- {
- case SERVICE_CONTROL_CONTINUE:
- g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
- break;
- case SERVICE_CONTROL_PAUSE:
- g_ServiceStatus.dwCurrentState = SERVICE_PAUSED;
- break;
- case SERVICE_CONTROL_STOP:
- g_ServiceStatus.dwCheckPoint = 0;
- g_ServiceStatus.dwWaitHint = 0;
- g_ServiceStatus.dwWin32ExitCode = 0;
- g_bService = false;
- g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
- break;
- default:
- break;
- }
- ServiceControl(dwCtrlCode); //不要这句也可以
- if(!SetServiceStatus(g_hServiceStatus,&g_ServiceStatus))
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- }
- }
7.服务执行体函数:
主要功能:服务的功能实现
- void DNetTimeSrvProc()
- {
- HANDLE hFile = CreateFile("c://testap//test.dat",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,
- NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
- if(hFile == INVALID_HANDLE_VALUE)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,GetErrMsg(GetLastError()));
- return;
- }
- SYSTEMTIME st;
- GetSystemTime(&st);
- char cText[20];
- sprintf(cText,"%04d-%02d-%02d %02d:%02d:%02d",st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
- DWORD dwSize = 20;
- WriteFile(hFile,cText,dwSize,&dwSize,NULL);
- CloseHandle(hFile);
- Sleep(1000);
- }
8.其它函数:
主要功能:服务程序的一些不怎么重要的东东
- BOOL ServiceStart()
- { //这个功能没用上
- SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
- if(NULL == hSCM)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return false;
- }
- SC_HANDLE hService = OpenService(hSCM,TEXT(IDS_SERVICENAME),SERVICE_ALL_ACCESS);
- if(NULL == hService)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- CloseServiceHandle(hSCM);
- return false;
- }
- if(!StartService(hService,0,NULL))
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return false;
- }
- LogEvent(EVENTLOG_INFORMATION_TYPE,TEXT("Service Started"));
- return true;
- }
- BOOL ServiceControl(DWORD dwControlID)
- {
- SC_HANDLE hSCM = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
- if(NULL == hSCM)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- return false;
- }
- SC_HANDLE hService = OpenService(hSCM,TEXT(IDS_SERVICENAME),SERVICE_STOP | SERVICE_RUNNING | SERVICE_PAUSED);
- if(NULL == hService)
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- CloseServiceHandle(hSCM);
- return false;
- }
- if(!ControlService(hService,dwControlID,&g_ServiceStatus))
- {
- LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCM);
- return false;
- }
- CloseServiceHandle(hService);
- CloseServiceHandle(hSCM);
- return true;
- }
- void LogEvent(WORD wType,LPCTSTR lpszText)
- {
- HANDLE hLogSouce = RegisterEventSource(NULL,TEXT(IDS_APPNAME));
- if(hLogSouce == NULL)
- {
- return;
- }
- ReportEvent(hLogSouce,wType,0,GetLastError(),NULL,1,0,&lpszText,NULL);
- DeregisterEventSource(hLogSouce);
- }
- LPCTSTR GetErrMsg(DWORD dwCode)
- {
- LPVOID lpBuf;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- 0,dwCode,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),(LPSTR)&lpBuf,0,NULL);
- return (LPCTSTR)lpBuf;
- }