c/c++ 创建一个服务应用程序

#include <stdio.h>
#include <windows.h>
#include <winsvc.h>


typedef enum __bool { false = 0, true = 1, } bool;
//定义一些全局变量和函数
void ServiceMain(DWORD argc, LPTSTR *argv); 
void ServiceCtrlHandler(DWORD dwControlCode);
//SCM报告服务状态信息
BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode,
DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,
DWORD dwWaitHint);
BOOL InitThread(); //创建线程来运行我们的任务
DWORD sysnap(LPDWORD param); //我们这个服务所要完成的任务
HANDLE hServiceThread; 
void KillService(); 
char *strServiceName = "sysnap"; 标识服务的内部名
SERVICE_STATUS_HANDLE nServiceStatusHandle; //存储调用RegisterServiceCtrlHandler返回的句柄
HANDLE killServiceEvent;
BOOL nServiceRunning;
DWORD nServiceCurrentStatus;
FILE * Fces=NULL;


void main(int argc, char *argv[])
{
	SERVICE_TABLE_ENTRY servicetable[]={{strServiceName,(LPSERVICE_MAIN_FUNCTION)ServiceMain},{NULL,NULL}};
	BOOL success;
 	// StartServiceCtrlDispatcher 函数负责把程序主线程连接到服务控制管理程序
	success=StartServiceCtrlDispatcher(servicetable);
	if(!success)
		{
			printf("fialed!");
		}
}


void ServiceMain(DWORD argc, LPTSTR *argv)
{
	BOOL success;
	//把ServiceCtrlHandler注册为服务控制器,接受来自SCM的请求并做出处理,
	nServiceStatusHandle=RegisterServiceCtrlHandler(strServiceName,(LPHANDLER_FUNCTION)ServiceCtrlHandler);
	//判断是否注册成功,否则返回
	if(!nServiceStatusHandle){return;}	
	//注册成功后向SCM报告服务状态信息,因为服务还没初始化完成,所以当前服务状态为SERVICE_START_PENDING
	success=ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,0,1,3000);
	if(!success){return;}
	//创建一个事件,在函数的最后将用该事件来保持函数的运行直到SCM发出停止请求才返回
	killServiceEvent=CreateEvent(0,TRUE,FALSE,0);
	if(killServiceEvent==NULL){return;}
	//向SCM报告服务状态信息
	success=ReportStatusToSCMgr(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
	if(!success){return;}
	//我们的服务开始运行任务了,当前状态设置为SERVICE_RUNNING
	nServiceCurrentStatus=SERVICE_RUNNING;
	success=ReportStatusToSCMgr(SERVICE_RUNNING,NO_ERROR,0,0,0);
	if(!success){return;}
    //InitThread()创建一个线程来运行我们的sysnap()函数
	success=InitThread();
	if(!success){return;}
	//sysnap()函数运行完了之后返回ServiceMain(),ServiceMain()调用WaitForSingleObject,因为服务被停止之前ServiceMain()不会结束
	WaitForSingleObject(killServiceEvent,INFINITE);
	CloseHandle(killServiceEvent);
}


//向SCM报告服务状态信息,可以说是更新信息吧,它接受的参数都是SERVICE_STATUS结构成员


BOOL ReportStatusToSCMgr(DWORD dwCurrentState, DWORD dwWin32ExitCode,DWORD dwServiceSpecificExitCode, DWORD dwCheckPoint,DWORD dwWaitHint)
	{
		BOOL success;
		SERVICE_STATUS nServiceStatus; //定义一个SERVICE_STATUS类型结构nServiceStatus
		nServiceStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS; //表示我们的服务是独占一个进程的服务
		nServiceStatus.dwCurrentState=dwCurrentState; //当前服务状态
		if(dwCurrentState==SERVICE_START_PENDING) 
			{
				nServiceStatus.dwControlsAccepted=0; //服务的初始化没有完成
			}
		else
			{
				nServiceStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_SHUTDOWN; //通知 SCM 服务接受哪个域。这里允许 STOP 和SHUTDOWN 请求
			}
			//dwServiceSpecificExitCode在你终止服务并报告退出细节时很有用。初始化服务时并不退出,因此值为 0
		if(dwServiceSpecificExitCode==0)
			{
				nServiceStatus.dwWin32ExitCode=dwWin32ExitCode;
			}
		else
			{
				nServiceStatus.dwWin32ExitCode=ERROR_SERVICE_SPECIFIC_ERROR;
			}
		nServiceStatus.dwServiceSpecificExitCode=dwServiceSpecificExitCode;
		nServiceStatus.dwCheckPoint=dwCheckPoint;
		nServiceStatus.dwWaitHint=dwWaitHint;
		//设置好nServiceStatus后,向SCM报告服务状态
		success=SetServiceStatus(nServiceStatusHandle,&nServiceStatus);
		if(!success)
		{
			KillService();
			return success;
		}
		else
			return success;
		}


BOOL InitThread()
	{
		DWORD id;
		hServiceThread=CreateThread(0,0,(LPTHREAD_START_ROUTINE)sysnap,0,0,&id);
		if(hServiceThread==0)
			{
				return false;
			}
		else
			{
				nServiceRunning=true;
				return true;
			}
	}


DWORD sysnap(LPDWORD param)
	{
		int c=0;
		while(nServiceRunning)
			{
				Fces = fopen("c:\\1.txt","at+");
				fprintf(Fces,"服务正在运行%i\n",c); 
				Sleep(1000);
				c+=1;
				fclose(Fces);
			}
		return 0;
	}


void KillService()
	{
		nServiceRunning=false;
		Fces = fopen("c:\\1.txt","at+");
		SetEvent(killServiceEvent);
		fprintf(Fces,"服务以停止!");
		fclose(Fces);
		ReportStatusToSCMgr(SERVICE_STOPPED,NO_ERROR,0,0,0);
	}


void ServiceCtrlHandler(DWORD dwControlCode)
	{
		BOOL success;
		switch(dwControlCode)
			{
				case SERVICE_CONTROL_SHUTDOWN: 
						break;
				case SERVICE_CONTROL_STOP:
						nServiceCurrentStatus=SERVICE_STOP_PENDING;
						success=ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,0,1,3000);//先更新服务状态为SERVICDE_STOP_PENDING,再停止服务
						KillService();
						return;
						default:
						break;
			}
		ReportStatusToSCMgr(nServiceCurrentStatus,NO_ERROR,0,0,0);
	}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值