//服务程序主函数。
#include "stdafx.h"
#include "Windows.h"
#include <iostream>
#include <fstream>
#define SZAPPNAME "serverSample" //服务程序名
#define SZSERVICENAME "serviceSample" //标识服务的内部名
//内部变量
bool bDebugServer=false;
SERVICE_STATUS ssStatus;
SERVICE_STATUS_HANDLE sshStatusHandle;
DWORD dwErr=0;
TCHAR szErr[256];
//下面的函数由程序实现
void WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv);
void WINAPI Service_Ctrl(DWORD dwCtrlCode);
void installService();
void removeService() { std::cout << L"removeService" << std::endl; }
void debugService(int argc,char** argv) { std::cout << L"debugService" << std::endl; }
//bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
//{
// std::cout << L"ReportStatusToSCMgr" << std::endl;
// return true;
//}
//
void AddToMessageLog(LPTSTR lpszMsg)
{
std::ofstream file1;
file1.open("e:\\nt.log",std::ios::app);
file1 << lpszMsg;
file1.close();
}
//BOOL SendStatusToSCM (DWORD dwCurrentState,
// DWORD dwWin32ExitCode,
// DWORD dwServiceSpecificExitCode,
// DWORD dwCheckPoint,
// DWORD dwWaitHint)
bool ReportStatusToSCMgr(DWORD dwCurrentState,DWORD dwWin32ExitCode,DWORD dwWaitHint)
{
BOOL success;
SERVICE_STATUS serviceStatus;
// Fill in all of the SERVICE_STATUS fields
serviceStatus.dwServiceType =SERVICE_WIN32_OWN_PROCESS;
serviceStatus.dwCurrentState = dwCurrentState;
// If in the process of something, then accept
// no control events, else accept anything
if (dwCurrentState == SERVICE_START_PENDING)
serviceStatus.dwControlsAccepted = 0;
else
serviceStatus.dwControlsAccepted =
SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE |
SERVICE_ACCEPT_SHUTDOWN;
// if a specific exit code is defines, set up
// the win32 exit code properly
//if (dwServiceSpecificExitCode == 0)
// serviceStatus.dwWin32ExitCode =dwWin32ExitCode;
//else
// serviceStatus.dwWin32ExitCode = ERROR_SERVICE_SPECIFIC_ERROR;
//serviceStatus.dwServiceSpecificExitCode =dwServiceSpecificExitCode;
//serviceStatus.dwCheckPoint = dwCheckPoint;
serviceStatus.dwWaitHint = dwWaitHint;
// Pass the status record to the SCM
//SERVICE_STATUS_HANDLE serviceStatusHandle;
success = SetServiceStatus (sshStatusHandle,&serviceStatus);
if (!success)
{
AddToMessageLog("success...\n");
}
return success;
}
int _tmain(int argc, _TCHAR* argv[])
{
AddToMessageLog("main...\n");
SERVICE_TABLE_ENTRY dispatchTable[]=
{
{TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},
{ NULL,NULL}
};
char szBuf[1024] = {0};
sprintf(szBuf, "参数个数%d\n", argc);
AddToMessageLog(szBuf);
for (int i=0; i<argc; ++i)
{
char szBuf[1024] = {0};
sprintf(szBuf, "argv[%d]%s\n", i, argv[i]);
AddToMessageLog(szBuf);
}
if(argc>1)
{
if(_stricmp("install",argv[1])==0)
{
installService();
}
else if(_stricmp("remove",argv[1])==0)
{
removeService();
}
else if(_stricmp("debug",argv[1])==0)
{
bDebugServer=true;
debugService(argc,argv);
}
else
{ //如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用
//StartServiceCtrlDispatcher 函数。
AddToMessageLog("here\n");
printf("%s - install to install the service /n",SZAPPNAME);
printf("%s - remove to remove the service /n",SZAPPNAME);
printf("%s - debug to debug the service /n",SZAPPNAME);
printf("/n StartServiceCtrlDispatcher being called./n");
printf("This may take several seconds.Please wait./n");
if(!StartServiceCtrlDispatcher(dispatchTable))
AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
else
AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));
}
exit(0);
}
else
{ //如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用
//StartServiceCtrlDispatcher 函数。
AddToMessageLog("here\n");
printf("%s - install to install the service /n",SZAPPNAME);
printf("%s - remove to remove the service /n",SZAPPNAME);
printf("%s - debug to debug the service /n",SZAPPNAME);
printf("/n StartServiceCtrlDispatcher being called./n");
printf("This may take several seconds.Please wait./n");
if(!StartServiceCtrlDispatcher(dispatchTable))
AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
else
AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));
}
return 0;
}
//服务入口点函数
void ServiceStart(DWORD dwArgc,LPTSTR* lpszArgv) //具体服务的初始化入口函数
{
std::cout << L"ServiceStart" << std::endl;
AddToMessageLog("ServiceStart\n");
}
void WINAPI Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
{
AddToMessageLog("Service_Main\n");
//注册服务控制处理函数
sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
//如果注册失败
if(!sshStatusHandle)
{
AddToMessageLog("服务控制处理函数,注册失败。\n");
goto cleanup;
return;
}
//初始化 SERVICE_STATUS 结构中的成员
ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;
ssStatus.dwServiceSpecificExitCode=0;
//更新服务状态
if(!ReportStatusToSCMgr(
SERVICE_START_PENDING,//服务状态,The service is starting.
NO_ERROR, //退出码
3000)) //等待时间
goto cleanup; //更新服务状态失败则转向 cleanup
ServiceStart(dwArgc,lpszArgv);
ReportStatusToSCMgr(SERVICE_RUNNING,dwErr,0);
while(1)
{
//AddToMessageLog("running...\n");
Sleep(1000);
}
return;
cleanup:
//把服务状态更新为 SERVICE_STOPPED,并退出。
if(sshStatusHandle)
(void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);
}
void ServiceStop()
{
}
//控制处理程序函数
void WINAPI Service_Ctrl(DWORD dwCtrlCode)
{
char szBuf[1024] = {0};
sprintf(szBuf, "dwCtrlCode[%d]\n", dwCtrlCode);
AddToMessageLog(szBuf);
//处理控制请求码
switch(dwCtrlCode)
{
//先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。
case SERVICE_CONTROL_STOP:
{
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
ServiceStop(); //由具体的服务程序实现
ssStatus.dwCurrentState=SERVICE_STOPPED;
ReportStatusToSCMgr(SERVICE_STOPPED,NO_ERROR,0);
return ;
}
//暂停服务
case SERVICE_CONTROL_PAUSE:
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
//ServicePause(); //由具体的服务程序实现
ssStatus.dwCurrentState=SERVICE_PAUSED;
return;
//继续服务
case SERVICE_CONTROL_CONTINUE:
ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
//ServiceContinue(); //由具体的服务程序实现
ssStatus.dwCurrentState=SERVICE_RUNNING;
return;
//更新服务状态
case SERVICE_CONTROL_INTERROGATE:
break;
//无效控制码
default:
break;
}
ReportStatusToSCMgr(ssStatus.dwCurrentState,NO_ERROR,0);
}
//安装服务程序
void installService()
{
SC_HANDLE schService;
SC_HANDLE schSCManager;
TCHAR szPath[512];
//得到程序磁盘文件的路径
if(GetModuleFileName(NULL,szPath,512)==0)
{
_tprintf(TEXT("Unable to install %s - %s /n"),
TEXT(SZAPPNAME),
GetLastError());//@1获取调用函数返回的最后错误码
return;
}
//打开服务管理数据库
schSCManager=OpenSCManager(
NULL, //本地计算机
NULL, //默认的数据库
SC_MANAGER_ALL_ACCESS //要求所有的访问权
);
if(schSCManager)
{
//登记服务程序
schService=CreateService(
schSCManager, //服务管理数据库句柄
TEXT(SZSERVICENAME), //服务名
TEXT(SZAPPNAME), //用于显示服务的标识
SERVICE_ALL_ACCESS, //响应所有的访问请求
SERVICE_WIN32_OWN_PROCESS, //服务类型
SERVICE_DEMAND_START, //启动类型
SERVICE_ERROR_NORMAL, //错误控制类型
szPath, //服务程序磁盘文件的路径
NULL, //服务不属于任何组
NULL, //没有tag标识符
NULL, //启动服务所依赖的服务或服务组,这里仅仅是一个空字符串
NULL, //LocalSystem 帐号
NULL);
if(schService)
{
_tprintf(TEXT("%s installed. /n"),TEXT(SZAPPNAME));
CloseServiceHandle(schService);
}
else
{
_tprintf(TEXT("CreateService failed - %d /n"),GetLastError());
}
CloseServiceHandle(schSCManager);
}
else
_tprintf(TEXT("OpenSCManager failed - %s /n"),GetLastError());
}
编写c++服务
最新推荐文章于 2019-12-25 20:58:21 发布