参考文章:http://blog.csdn.net/yuchongjike/article/details/6137823
http://www.360doc.com/content/12/0828/09/10473672_232744894.shtml
// ServiceUSB.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <time.h>
#define LOG_ERR 0
#define LOG_INFO 1
#define LOG_WARNING 2
#define LOG_FILE_NAME "C:\\lclog\\log.txt"
#define APPNAME "USBSrv" //应用程序名
#define SERVICENAME "USBSrv" //服务名称
#define SERVICEDESC "USB check service" //服务描述
void InstallService(); //安装服务
void UnInstallService(); //删除服务
void WINAPI ServiceMain_DNetTime(DWORD dwArgc,LPTSTR *lpArgv); //服务处理主函数,注册服务
void WINAPI ServiceCtrlHandle(DWORD dwCtrlCode); //服务控制,注册服务时用
void LogEvent(WORD wType,LPCTSTR lpszText); //事件记录
DWORD WINAPI Service(LPVOID lpvThread); //服务功能函数 写想要做的事
int writelog(int nLogLevel,char *pcFormat,...);
LPCTSTR GetErrMsg(DWORD dwCode);
BOOL ServiceControl(DWORD dwControlID);
BOOL ServiceStart();
SERVICE_STATUS g_ServiceStatus; //记录服务状态
SERVICE_STATUS_HANDLE g_hServiceStatus; //注册服务时返回值,服务控制时用
BOOL g_bService; //一个标记,退出执行体用.可以换成事件
int main(int argc, char* argv[])
{
writelog(LOG_INFO,"main");
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[] =
{
{SERVICENAME,ServiceMain_DNetTime}, //服务名,服务处理主函数
{NULL,NULL} //最后必须有一个NULL
};
if(!StartServiceCtrlDispatcher(ste)) //服务事件分派
{
LogEvent(EVENTLOG_ERROR_TYPE,GetErrMsg(GetLastError()));
return -1;
}
return 0;
}
void LogEvent(WORD wType,LPCTSTR lpszText)
{
writelog(LOG_INFO,"LogEvent");
HANDLE hLogSouce = RegisterEventSource(NULL,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;
}
BOOL ServiceStart()
{
writelog(LOG_INFO,"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(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)
{
writelog(LOG_INFO,"ServiceControl");
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(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 WINAPI ServiceCtrlHandle(DWORD dwCtrlCode)
{
writelog(LOG_INFO,"ServiceCtrlHandle");
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;
if(SetServiceStatus(g_hServiceStatus, &g_ServiceStatus) == 0)
{
//SetServiceStatus error!
}
break;
default:
break;
}
ServiceControl(dwCtrlCode); //不要这句也可以
if(!SetServiceStatus(g_hServiceStatus,&g_ServiceStatus))
{
LogEvent(EVENTLOG_ERROR_TYPE,TEXT(GetErrMsg(GetLastError())));
}
}
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(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;
//服务实现
if(bService)
{
HANDLE hThread = CreateThread(NULL,
0,
Service,
NULL,
0,
NULL);
if(hThread == NULL)
{
//CreateThread error!
return;
}
CloseHandle(hThread);}
}
void UnInstallService()
{
writelog(LOG_INFO,"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(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);
}
void InstallService()
{
writelog(LOG_INFO,"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(SERVICENAME),TEXT(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 = 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");
}
int writelog(int nLogLevel,char *pcFormat,...)
{
char szBuf[16];
char szRename[256];
int iRc=0;
memset(szBuf,0,sizeof(szBuf));
memset(szRename,0,sizeof(szRename));
time_t now;
now=time(NULL);
struct tm *tp;
tp =localtime(&now);
//int iFileSize =0;
FILE *fp =NULL;
fp=fopen(LOG_FILE_NAME,"a+");
if(fp==NULL)
{
//writelog(LOG_ERR,"open the file %s failed\n",FILE_NAME);
//MessageBox("open the file failed");
return 1;
}
//iFileSize= get_file_size(LOG_FILE_NAME);
if (nLogLevel ==LOG_INFO ) {
strcpy(szBuf,"<INFO:");
}else if(nLogLevel==LOG_WARNING){
strcpy(szBuf,"<WARN:");
}else if(nLogLevel==LOG_ERR){
strcpy(szBuf,"<ERR: ");
}else{
strcpy(szBuf,"~~~~~");
}
fprintf(fp,"%s %02d:%02d:%02d>",szBuf,tp->tm_hour,tp->tm_min,tp->tm_sec);
va_list argptr;
va_start(argptr,pcFormat);
vfprintf(fp,pcFormat,argptr);
va_end(argptr);
fclose(fp);
fp=NULL;
return 0;
}
//服务线程函数
DWORD WINAPI Service(LPVOID lpvThread)
{
writelog(LOG_INFO,"Service"); //实现函数功能的地方。
return 1;
}
遇到问题:停止服务时,总会提示1053的错误,但服务还是会停止
解决途径:对于“错误1053:服务没有及时响应启动或控制请求”,我郁闷了一下午,后来在调试发现是单线程泵式等待,导致服务在60秒没有响应,所以 Windows 服务控制器会将此服务标记为“超时”。通过设置dwWaitHint 也没有解决问题,根本的解决办法是设置成多线程。
ServiceMain_DNetTime函数中添加:
HANDLE hThread = CreateThread(NULL,
0,
Service,
NULL,
0,
NULL);
if(hThread == NULL)
{
//CreateThread error!
return;
}
CloseHandle(hThread);}
可以成功的解决关闭服务出错的问题。
使用方法:
在控制台下输入 ServiceUSB /Install 或者 ServiceUSB -Install
开启服务:ServiceUSB /Start
卸载服务:ServiceUSB /UnInstall
可以通过在控制台输入:services.msc 查看服务