编写c++服务

//服务程序主函数。

#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());

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值