zoukankan      html  css  js  c++  java
  • 基于visual c++之windows核心编程代码分析(35)实践NT服务的框架

    NT指的是计算机操作系统的核心,有NT4.0/server2000/xp/server2003/vista/2008.是微软NT系列NT服务器网络是计算机网络中服务器是NT型主机。

    一个NT服务有三部分构成:
    1:Service Control Manager(SCM) 每个WIN NT/2K都有一个SCM,他存在于Service.exe中.
    2:服务本身一个服务拥有能从SCM受到信号和命令所必需的特殊代码,并能够在处理后将他的状态返回SCM.
    3:Service Control Dispatcher(SCP) 他是一个拥有用户截面,允许用户开始,暂停,继续,并且控制已经安装在计算机上作为服务运行的WIN32

    下面我们来见实践NT服务的框架,编写一个完整的NT服务。

    #include <stdio.h>
    #include <windows.h>
    SERVICE_STATUS m_ServiceStatus;
    SERVICE_STATUS_HANDLE m_ServiceStatusHandle;
    BOOL bRunning=true;
    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);//服务主函数
    void WINAPI ServiceCtrlHandler(DWORD Opcode);//服务控制函数
    void WINAPI CmdStart(void);//要启动的程序函数
    BOOL InstallService();   //安装服务的函数
    BOOL DeleteService();    //删除服务的函数
    
    int main(int argc, char* argv[])
    {
    	printf("\twindows based service demo\n");
    	printf("\tgxisone@hotmail.com\n");
        if(argc!=3)
    	{
    		printf("usage: %s -install[remove]",argv[0]);
    		return 0;
    	}
    		if(strcmp(argv[1],"-install")==0)                    /// install
    		{
    			if(InstallService())
    				printf("\n\nService Installed Sucessfully\n");
    			else
    				printf("\n\nError Installing Service\n");
    		}
    	else if(strcmp(argv[1],"-remove")==0)    // remove
    		{
    			if(DeleteService())
    				printf("\n\nService remove sucessfully\n");
    			else
    				printf("\n\nError removing Service\n");
    		} 
    		else
    		{
    			printf("\nusage: %s -install[remove]\n",argv[0]);
    			return 0;
    		}
    //在进入点函数里面要完成ServiceMain的初始化,
    //准确点说是初始化一个SERVICE_TABLE_ENTRY结构数组,
    //这个结构记录了这个服务程序里面所包含的所有服务的名称
    //和服务的进入点函数
    SERVICE_TABLE_ENTRY 
    DispatchTable[]={{"WindowsMgr",ServiceMain},{NULL,NULL}};
    //最后的NULL指明数组的结束
    	  StartServiceCtrlDispatcher(DispatchTable); 
    		return 0;
    }
    
    void WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
    {
    	m_ServiceStatus.dwServiceType = SERVICE_WIN32;
    	m_ServiceStatus.dwCurrentState = SERVICE_START_PENDING; 
    	m_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    	m_ServiceStatus.dwWin32ExitCode = 0; 
    	m_ServiceStatus.dwServiceSpecificExitCode = 0; 
    	m_ServiceStatus.dwCheckPoint = 0; 
    	m_ServiceStatus.dwWaitHint = 0;
    	m_ServiceStatusHandle = RegisterServiceCtrlHandler("WindowsMgr",ServiceCtrlHandler);
    	if (m_ServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)return; 
    	m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; //设置服务状态
    	m_ServiceStatus.dwCheckPoint = 0; 
    	m_ServiceStatus.dwWaitHint = 0; 
    //SERVICE_STATUS结构含有七个成员,它们反映服务的现行状态。
    //所有这些成员必须在这个结构被传递到SetServiceStatus之前正确的设置
    SetServiceStatus (m_ServiceStatusHandle, &m_ServiceStatus);
     	bRunning=true;
    	//*
        CmdStart(); //启动我们的服务程序
    	//*
    	return; 
    }
    void WINAPI ServiceCtrlHandler(DWORD Opcode)//服务控制函数
    {
    	switch(Opcode) 
    	{ 
    	case SERVICE_CONTROL_PAUSE:    // we accept the command to pause it
    		m_ServiceStatus.dwCurrentState = SERVICE_PAUSED; 
    		break; 
    	case SERVICE_CONTROL_CONTINUE:  // we got the command to continue
    		m_ServiceStatus.dwCurrentState = SERVICE_RUNNING; 
    		break; 
    	case SERVICE_CONTROL_STOP:   // we got the command to stop this service
    		m_ServiceStatus.dwWin32ExitCode = 0; 
    		m_ServiceStatus.dwCurrentState = SERVICE_STOPPED; 
    		m_ServiceStatus.dwCheckPoint = 0; 
    		m_ServiceStatus.dwWaitHint = 0; 
    		SetServiceStatus (m_ServiceStatusHandle,&m_ServiceStatus);
    		bRunning=false;
    		break;
    	case SERVICE_CONTROL_INTERROGATE: // 
    		break; 
    	} 
    	return; 
    }
    BOOL InstallService()   //安装服务函数
    {
    	char strDir[1024];
    	SC_HANDLE schSCManager,schService;
    	GetCurrentDirectory(1024,strDir);
    	GetModuleFileName(NULL,strDir,sizeof(strDir));
    
    	char chSysPath[1024];
    	GetSystemDirectory(chSysPath,sizeof(chSysPath));
    
    	strcat(chSysPath,"\\WindowsMgr.exe");
    if(!CopyFile(strDir,chSysPath,FALSE))printf("Copy file OK\n");                    // 把我们的服务程序复制到系统根目录
    
    	strcpy(strDir,chSysPath);
    schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS); 
    	if (schSCManager == NULL) 
    	{
    		printf("open scmanger failed,maybe you do not have the privilage to do this\n");
    		return false;
    	}
    
    	LPCTSTR lpszBinaryPathName=strDir;
    	
    	schService = CreateService(schSCManager,"WindowsMgr","Windows Manger Control", //将服务的信息添加到SCM的数据库
    		SERVICE_ALL_ACCESS, // desired access 
    		SERVICE_WIN32_OWN_PROCESS, // service type 
    		SERVICE_AUTO_START, // start type 
    		SERVICE_ERROR_NORMAL, // error control type 
    		lpszBinaryPathName, // service's binary 
    		NULL, // no load ordering group 
    		NULL, // no tag identifier 
    		NULL, // no dependencies 
    		NULL, // LocalSystem account 
    		NULL); // no password 
    
    		if (schService == NULL) 
    	{
    		printf("faint,we failed just because we invoke createservices failed\n");
    		return false; 
    	}
    	CloseServiceHandle(schService); 
    	return true;
    }
    BOOL DeleteService()
    {
    	SC_HANDLE schSCManager;
    	SC_HANDLE hService;
    	schSCManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
    
        char chSysPath[1024];
    	GetSystemDirectory(chSysPath,sizeof(chSysPath));
        strcat(chSysPath,"\\WindowsMgr.exe");
    
    	if (schSCManager == NULL) 
    	{
    		printf("faint,open scmanger failed\n");
    		return false; 
    	}
    	hService=OpenService(schSCManager,"WindowsMgr",SERVICE_ALL_ACCESS);
    	if (hService == NULL) 
    	{
    		printf("faint,open services failt\n");
    		return false;
    	}
        if(DeleteFile(chSysPath)==0)
    		{
    			printf("Dell file Failure !\n");               
    			return false;
    		}
    	else printf("Delete file OK!\n");
    	if(DeleteService(hService)==0)
    		return false;
        
    	if(CloseServiceHandle(hService)==0)
    		return false;
    	else
    		return true;
    }
    
    void WINAPI CmdStart(void)
    {
    //--------------------------------
    //把你的要做成服务启动的程序代码添加到这里
    //那么你的代码就可以作为NT服务启动了
    //--------------------------------
    }


     

  • 相关阅读:
    hadoop的namenode故障处理方法
    hadoop的checkpoint检查时间参数设置
    hadoop配置历史服务器&&配置日志聚集
    hadoop_批量命令脚本&同步文件脚本
    查看centos操作系统、java_jdk、hadoop位数
    hadoop的namenode启动失败
    shell_语法
    Mycat入门配置_读写分离配置
    VM虚拟机克隆_修改网络
    ssh免密登陆及时间设置
  • 原文地址:https://www.cnblogs.com/new0801/p/6177796.html
Copyright © 2011-2022 走看看