用C/C++编写的Window服务一例

用C/C++编写的Window服务一例

//NTServiceC.cpp
//用C/C++编写的Window服务一例
//安装与反安装批处理.bat
//方法一:
//echo sc delete NTServiceC
//echo sc create NTServiceC binpath= E:\Debug\NTServiceC.exe
//方法二:
//NTServiceC.exe uninstall
//NTServiceC.exe install
//NTServiceC.exe exec
#pragma once
#include <windows.h>
#include <stdio.h>
#include <iostream>
//#include <comdef.h>
#include <tchar.h>
#include <comutil.h>

#define SLEEP_TIME 5000
#define LOGFILE "c:\\NTServiceC.txt"

using namespace std;
char* ServiceName="NTServiceC";

enum EnumRunState
{
	 None=0,
     Running=1,
	 Stoped=2,
	 Pause=3,
};

EnumRunState RunState;

WCHAR* CharPtr2ACharPtr(const char* src)
{
	// Convert to a wchar_t*
    size_t srcsize = strlen(src) + 1;
    size_t newsize = srcsize;	
    size_t convertedChars = 0;
    wchar_t *wcstring;
	wcstring=new wchar_t[newsize];
    mbstowcs_s(&convertedChars, wcstring, srcsize, src, _TRUNCATE);
    //wcscat_s(wcstring, L" (wchar_t *)");
    //wcout << wcstring << endl;
	return wcstring;
};

int WriteToLog(char* str)
{
    FILE* log;
	log=fopen(LOGFILE,"a+");
	if(log==NULL)  return 0;
	fprintf(log,"%s\n",str);
	fclose(log);
	return 1;
}

//定义变量和方法
SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;
HANDLE terminateEvent; //事件
HANDLE threadHandle;   //线程
VOID terminate(DWORD error);
void ServiceMain(int argc,char** argv);
void ControlHandler(DWORD request);
int InitService();
//
BOOL RunService(WCHAR* sSvcName);
VOID ResumeService();
VOID PauseService();
VOID StopService();
//
BOOL SendStatusToSCM (DWORD dwCurrentState,
   DWORD dwWin32ExitCode, 
   DWORD dwServiceSpecificExitCode,
   DWORD dwCheckPoint,
   DWORD dwWaitHint);
//
void InstallService();
void UninstallService();
//
DWORD WINAPI ServiceThread(LPDWORD param);
//安装入口点
void main(int argc, char* argv[])
{
	WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
	//方法一	
     SERVICE_TABLE_ENTRY ServiceTable[2];
	 //设置服务名称和服务入口函数	 
     ServiceTable[0].lpServiceName=TServiceName;
	 ServiceTable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;
	 ServiceTable[1].lpServiceName=NULL;
	 ServiceTable[1].lpServiceProc=NULL;
     
	 //方法二     
	 /*SERVICE_TABLE_ENTRY  ServiceTable[]=  
	 {
		  {TEXT(ServiceName),(LPSERVICE_MAIN_FUNCTION)ServiceMain},  
		  { NULL,NULL}
	 };*/
	 //注册为服务和反注册
	 //-------------------------------------------------
     //引数 
	 if(argc<=1)
	 {
		  //usage(使用方法)表示   
		  cout<<"使用方法:"<<endl;
		  //cout<<"zxz\"zxz"<<ENDL;
		  //"install"
		  cout<<"\"install\""; 
		  //"or"
		  cout<<"or";
		  //"uninstall"
		  cout<<"\"uninstall\"";
		  //"exec"
		  cout<<"\"exec \""; 
		  cout<<" parameter required in the command line"<<endl;	  
	 } 
	 if(argc>1)
	 {
		  if(_stricmp("install",argv[1])==0)
		  {   //install(InstallService)
			  InstallService(); 
			  cout<<"installService Succed!"<<endl;
		  }		    
		  else if(_stricmp("uninstall",argv[1])==0)
		  {   //uninstall(UninstallService) 
			  UninstallService(); 
			  cout<<"UninstallService Succed!"<<endl;
		  }		  
		  else if(_stricmp("exec",argv[1])==0)
		  {   //exec(ServiceMain)
			  RunService(TServiceName);		   
		  } 
		  else
		  {    //usage(使用方法)表示
			   cout<<"使用方法 :"<<endl;
			   //"install"
			   cout<<"\"install\""; 
			   //"or"
			   cout<<"or";
			   //"uninstall"
			   cout<<"\"uninstall\"";
			   //"exec"
			   cout<<"\"exec \""; 
			   //"or"
			   cout<<"or";
			   cout<<" parameter required in the command line"<<endl;
		  }
	 }
	 //-------------------------------------------------
	 //启动服务的控制分派机线程(启动并执行一个新线程)
	 StartServiceCtrlDispatcher(ServiceTable);
}


//服务入口点(主线程)
void ServiceMain(int argc,char** argv)
{
	WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
    int success;
	//success=InitService();
	//if(!success)
	//{
    //       //初始化失败,终止服务
	//	WriteToLog("ServiceMain::InitService初始化失败,终止服务");
	//	ServiceStatus.dwCurrentState=SERVICE_STOPPED;
	//	ServiceStatus.dwWin32ExitCode=-1;
	//	SetServiceStatus(hStatus,&ServiceStatus);
	//	//退出ServiceMain
	//	return;
	//}
	//开始服务
	RunService(TServiceName);

	//注册服务控制处理函数
   hStatus = RegisterServiceCtrlHandler(TServiceName,(LPHANDLER_FUNCTION)ControlHandler);   
   if(!hStatus)
   {	
	   WriteToLog("ServiceMain函数中注册服务控制处理函数失败!\n");
	   return;
   }
	//向SCM报告工作状态
	RunState=EnumRunState::Running;
    ServiceStatus.dwCurrentState=SERVICE_RUNNING;
	ServiceStatus.dwServiceType=SERVICE_WIN32;
    ServiceStatus.dwControlsAccepted = 
			SERVICE_ACCEPT_STOP |
			SERVICE_ACCEPT_PAUSE_CONTINUE |
			SERVICE_ACCEPT_SHUTDOWN;
	/*SetServiceStatus(hStatus,&ServiceStatus);*/
	
   启动工作循环(这个模块在另外一个线程中执行)
   //while(RunState==EnumRunState::Running)
   //{
	  //  WriteToLog("ServiceMain函数写日志\n");
   //     Sleep(500);
   //}
   //创建一个终结事件
   terminateEvent = CreateEvent (0,TRUE,FALSE,0);
   if (!terminateEvent)
   {
       terminate(GetLastError());
       return;
   }   
   //
   success =  SendStatusToSCM(SERVICE_START_PENDING,NO_ERROR,0,2,1000);
   if (!success)
   {
		terminate(GetLastError()); 
		return;
   }   
   //初始化
   success =  InitService();
   if (!success)
   {
		terminate(GetLastError());
		return;
   }      
   success = SendStatusToSCM(SERVICE_RUNNING,NO_ERROR,0,0,0);
   if (!success)
   {
		terminate(GetLastError()); 
		return;
   }   
   //等待停止
   WaitForSingleObject ( terminateEvent, INFINITE);
      
   terminate(0);
   WriteToLog("ServiceMain函数执行完毕!");
}
//服务控制台命令处理函数
void ControlHandler(DWORD request)
{
   DWORD  currentState = 0;
   BOOL success; 
   WriteToLog("ControlHandler:"+request);
   switch(request)
   { 
	   case SERVICE_CONTROL_STOP:
		    RunState=EnumRunState::Stoped;
			currentState = SERVICE_STOP_PENDING;
			ServiceStatus.dwCurrentState=currentState;
			SetServiceStatus(hStatus,&ServiceStatus);		    
			StopService();
			return;
	   case SERVICE_CONTROL_PAUSE:	
		     RunState=EnumRunState::Pause;
			 currentState = SERVICE_PAUSED;
			 ServiceStatus.dwCurrentState=currentState;
			 SetServiceStatus(hStatus,&ServiceStatus);
			 PauseService();
			break;
	   case SERVICE_CONTROL_CONTINUE:	
		   RunState=EnumRunState::Running;
			 currentState = SERVICE_RUNNING;
			 ServiceStatus.dwCurrentState=currentState;
			 SetServiceStatus(hStatus,&ServiceStatus);
			 ResumeService();
			break;
	   case SERVICE_CONTROL_INTERROGATE:
			// it will fall to bottom and send status
			break;
	    
		// Do nothing in a shutdown. Could do cleanup
		// here but it must be very quick.
	   case SERVICE_CONTROL_SHUTDOWN:
			// Do nothing on shutdown		   
			return;
	   default:
			break;
   }   
   //ServiceStatus.dwCurrentState=currentState;
   //SetServiceStatus(hStatus,&ServiceStatus);
}
//初始化服务(开始服务时执行)
int InitService()
{
   int result;
   WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName); 
   //写日志信息
   result=WriteToLog("Monitoring started."); 
   //开始一个线程 Start the service's thread
   DWORD id;   
   threadHandle = CreateThread(0, 0,(LPTHREAD_START_ROUTINE)ServiceThread,0, 0, &id);   
   if (threadHandle==0)
   {
       result=0;
   }
   else
   {		
	   result=1;
   }
   //
   WriteToLog("InitService一个线程开始了!");
   return result;
}
DWORD WINAPI ServiceThread(LPDWORD param)
{ 
   //线程操作
	while(RunState==EnumRunState::Running)
	{
		WriteToLog("线程中写日志\n");
		Sleep(500);       
	}
   WriteToLog("线程操作ServiceThread完成!");
   return 0;
}


//

BOOL RunService(WCHAR* sSvcName)
{   
   SC_HANDLE schSCManager;
   SC_HANDLE scHandle;
   BOOL boolRet;

   // open to SCM   
   schSCManager = OpenSCManager(
		0,  
		0,  
		SC_MANAGER_ALL_ACCESS 
	);

   //Open
   scHandle = OpenService(
		schSCManager,              
		sSvcName, 
		SERVICE_ALL_ACCESS  
		);
   
   //start 
   boolRet = StartService(
		scHandle,          
		0,        
		NULL);  
   
   return boolRet;
}


VOID ResumeService()
{
   //pauseService=FALSE;
   //ResumeThread(threadHandle);
   return;
}
VOID PauseService()
{
   //pauseService = TRUE;
   //SuspendThread(threadHandle);
   return;
}
VOID StopService() 
{
	RunState=EnumRunState::Stoped;//=FALSE;
   // Set the event that is holding ServiceMain
   // so that ServiceMain can return
   SetEvent(terminateEvent);
}
//安装/反安装函数
void InstallService()
{ 
	 SC_HANDLE schService; 
	 SC_HANDLE schSCManager; 
	 TCHAR szPath[512];

	 WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
	 
	 //Install Starting... 
	 //获取模块文件路径名称
	 if(!GetModuleFileName(NULL,szPath,512)) 
	 {  
		 return;  
	 }
	 
	 // open to SCM 
	 schSCManager = OpenSCManager( 
								0,  // pointer to machine name string
								0,  // pointer to database name string
								SC_MANAGER_CREATE_SERVICE // type of access
								);
	 if (!schSCManager)
	 {
		 WriteToLog("OpenScManagerErrorID:"+GetLastError());  
		 return;
	 }
	 // Install 新服务
	 schService = CreateService(
			schSCManager, // handle to service control manager database
			TServiceName, // pointer to name of service to start
			TServiceName, // pointer to display name     
			SERVICE_ALL_ACCESS,// type of access to service
			SERVICE_WIN32_OWN_PROCESS|SERVICE_INTERACTIVE_PROCESS ,// type of service
			SERVICE_DEMAND_START,// when to start service
			SERVICE_ERROR_NORMAL,// severity if service fails to start
			szPath,       // pointer to name of binary file
			NULL,         // pointer to name of load ordering group
			NULL,         // pointer to variable to get tag identifier
			NULL,         // pointer to array of dependency names
			NULL,         // pointer to account name of service
			NULL          // pointer to password for service account
			);
	 if (!schService)
	 {  
		 WriteToLog("CreateServiceErrorID:"+GetLastError()); 
		  return;
	 }
	 else
	 {
		 WriteToLog("Service installed\n"); 
	 }	 
	 // clean up
	 CloseServiceHandle(schService);
	 CloseServiceHandle(schSCManager);	 
	 WriteToLog("Install Ending...\n"); 
}


void UninstallService()
{ 
	 SC_HANDLE schService;
	 SC_HANDLE schSCManager; 
	 BOOL success;
	 SERVICE_STATUS svcStatus;

	 WCHAR* TServiceName=CharPtr2ACharPtr(ServiceName);
	 
	 WriteToLog("Uninstall Starting...");
	 
	 // open to SCM 
	 schSCManager = OpenSCManager(
			0,// pointer to machine name string 
			0,// pointer to database name string
			SC_MANAGER_CREATE_SERVICE // type of access
			);
	 if (!schSCManager)
	 {
		 WriteToLog("OpenScManagerErrorID:"+GetLastError());
	     return;
	 }
	 
	 //打开一个服务
	 schService = OpenService(
				  schSCManager,              // handle to service control manager database
				  TServiceName,              // pointer to name of service to start
				  SERVICE_ALL_ACCESS | DELETE// type of access to service
				  );
	 if (!schService)
	 {
		  WriteToLog("OpenServiceErrorID:"+GetLastError());
		  return;
	 }
	 //(if necessary)
	 success = QueryServiceStatus(schService, &svcStatus);
	 if (!success)
	 {
		 WriteToLog("In QueryServiceStatus ErrorID:"+GetLastError());
		  return;
	 }
	 if (svcStatus.dwCurrentState != SERVICE_STOPPED)
	 {
		   WriteToLog("Stopping service...");
		   success = ControlService(
			   schService,           // handle to service
			   SERVICE_CONTROL_STOP, // control code
			   &svcStatus            // pointer to service status structure
		   );
		   if (!success)
		   {
			   WriteToLog("In ControlServiceErrorID:"+GetLastError());
			   return;
		   }
	 }
	 //等待
	 do
	 {
		  QueryServiceStatus(schService,&svcStatus);      
		  Sleep(500);    
	  
	 }while(SERVICE_STOP_PENDING==svcStatus.dwCurrentState);        
	 
	 if(SERVICE_STOPPED!=svcStatus.dwCurrentState)
	 {
		 WriteToLog("Failed to Stop Service ErrorID:"+GetLastError());  
	     return;
	 }
	 
	 //删除服务 
	 success = DeleteService(schService);
	 if (success)
	 {
	     WriteToLog("Service removed\n");
	 }
	 else
	 {
		 WriteToLog("In DeleteService ErrorID:"+GetLastError());
	     return;
	 }	 
	 //Clean up
	 CloseServiceHandle(schService);
	 CloseServiceHandle(schSCManager);	 
	 WriteToLog("Uninstal Ending...");
}

//
BOOL SendStatusToSCM (DWORD dwCurrentState,
   DWORD dwWin32ExitCode, 
   DWORD dwServiceSpecificExitCode,
   DWORD dwCheckPoint,
   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 (hStatus,&serviceStatus);
	   if (!success)
	   {
		  StopService();	 
	   }
	   return success;
  }
//
VOID terminate(DWORD error)
{
   // if terminateEvent has been created, close it.
   if (terminateEvent)
    CloseHandle(terminateEvent);
   
   // Send a message to the scm to tell about
   // stop age
   if (hStatus)
    SendStatusToSCM(SERVICE_STOPPED, error,
    0, 0, 0);
   
   // If the thread has started kill it off
   if (threadHandle)
    CloseHandle(threadHandle);
   
   // Do not need to close serviceStatusHandle
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值