windows 服务程序学习心得

         1.服务首先是一个win32的可执行程序,它受到操作系统的优待,伴随着操作系统启动而启动,关闭而关闭。

         2.服务绝不需要用户界面。大多是的服务都是运行在服务器上。服务通常以控制台程序被编写,函数的入口是main(),不是winmain()。

          3想要写一个服务,就必须熟悉Win NT/2000的安全机制,在上述操作系统之中,所有安全都是基于用户的。如果一个进程正在一个用户帐号下执行,那么这个进程就同时拥有这个用户所能拥有的一切访问权限,不论是在本机还是网络。系统帐号则是一个特殊的账号,它用来标识系统本身,而且运行在这个帐号下的任何进程都拥有系统上的所有访问权限,但是系统帐号不能在域上使用,无法访问网络资。当一个进程被产生的时候,它都是执行在一个用户的上下文(context)。服务也是Win32可执行程序,它也需要执行在一个context,通常服务都是在系统账号下运行,但是也可以根据情况选择让它运行在一个用户账号下,也就会因此获得相应的访问资源的权限。          

4.服务程序通常编写成控制台类型的应用程序,总的来说,一个遵守服务控制管理程序接口要求的程序

      包含下面三个函数:

1、服务程序主函数(main):调用系统函数 StartServiceCtrlDispatcher连接程序主线程到服务控制管理程序。

2、服务入口点函数(ServiceMain):执行服务初始化任务,同时执行多个服务的服务进程有多个服务入口函数。

3、控制服务处理程序函数(Handler):在服务程序收到控制请求时由控制分发线程引用。

  5另外在系统运行此服务之前需要安装登记服务程序:installService函数。删除服务程序则需要先删除服务安装登记:removeService 函数。

服务程序主函数

     

int _tmain(int argc, _TCHAR* argv[])
{    
	if((argc==2)&&(*argv[1]=='-'))
	{	
		if(_tcscmp(_T("install"),argv[1]+1)==0)
		{
			installService();
		}
		else if(_tcscmp(_T("remove"),argv[1]+1)==0)
		{
			removeService();
		}
	}
	//如果未能和上面的如何参数匹配,则可能是服务控制管理程序来启动该程序。立即调用
	//StartServiceCtrlDispatcher 函数。
	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");
			
	SERVICE_TABLE_ENTRY dispatchTable[]={
			{TEXT(SZSERVICENAME),(LPSERVICE_MAIN_FUNCTION)Service_Main},
			{NULL,NULL}
			};
	bool ret=StartServiceCtrlDispatcher(dispatchTable);		
	if(!ret)
		AddToMessageLog(TEXT("StartServiceCtrlDispatcher failed."));
	else
		AddToMessageLog(TEXT("StartServiceCtrlDispatcher OK."));
    return 0;

}


服务入口函数

//服务入口点函数
 void  WINAPI  Service_Main(DWORD dwArgc, LPTSTR *lpszArgv)
{	
	//初始化 SERVICE_STATUS 结构中的成员
    ssStatus.dwServiceType=SERVICE_WIN32_OWN_PROCESS;	 
	ssStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP; 
	ssStatus.dwCurrentState= SERVICE_START_PENDING;     
	ssStatus.dwServiceSpecificExitCode=0;	 
	ssStatus.dwCheckPoint=0;
	ssStatus.dwWin32ExitCode=0;
	ssStatus.dwWaitHint=0;
	SetServiceStatus(sshStatusHandle,&ssStatus);  

	//注册服务控制处理函数
    sshStatusHandle=RegisterServiceCtrlHandler(TEXT(SZSERVICENAME),Service_Ctrl);
     //如果注册失败
    if(!sshStatusHandle)
    {
        goto cleanup;
        return;
    }    
     //更新服务状态
    if(!ReportStatusToSCMgr(
        SERVICE_RUNNING,//服务状态,The service is starting.
        NO_ERROR,            //退出码         
        3000))                   //等待时间
        goto cleanup;        //更新服务状态失败则转向 cleanup
    ServiceStart(dwArgc,lpszArgv);//具体的服务程序
    return;
cleanup:
    //把服务状态更新为 SERVICE_STOPPED,并退出。
    if(sshStatusHandle)
        (void)ReportStatusToSCMgr(SERVICE_STOPPED,dwErr,0);

}


 

控制处理函数

//控制处理程序函数

void WINAPI Service_Ctrl(DWORD dwCtrlCode)

{
     //处理控制请求码
     switch(dwCtrlCode)
     {
         //先更新服务状态为 SERVICDE_STOP_PENDING,再停止服务。
     case SERVICE_CONTROL_STOP:
         ReportStatusToSCMgr(SERVICE_STOP_PENDING,NO_ERROR,500);
       //  ServiceStop();     //由具体的服务程序实现
		 ssStatus.dwCurrentState=SERVICE_STOPPED;
		 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 - %s \n"),GetLastError());
         }
         CloseServiceHandle(schSCManager);
     }
     else
         _tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());

}


 

卸载函数

/*停止和安装已安装的服务*/
void removeService()
{
	SC_HANDLE	schService;
	SC_HANDLE	schSCManager;
	//打开服务管理数据库
	schSCManager=OpenSCManager(
					NULL,	//本地计算机
					NULL,	//默认的数据库
					SC_MANAGER_ALL_ACCESS	//要求所有的访问权
					);
	if(schSCManager)
	{
		//获取服务程序句柄
		schService=OpenService(
			schSCManager,			//服务管理数据库句柄
			TEXT(SZSERVICENAME),	//服务名
			SERVICE_ALL_ACCESS		//响应所有的访问请求
			);
		if(schService)
		{
			//试图停止服务
			if(ControlService(
				schService,				//服务程序句柄
				SERVICE_CONTROL_STOP,	//停止服务请求码
				&ssStatus				//接收最后的服务状态信息
				))
			{
				_tprintf(TEXT("Stopping %s."),TEXT(SZAPPNAME));
				Sleep(1000);

				//等待服务停止
				//
				while(QueryServiceStatus(schService,&ssStatus))
				{
					if(SERVICE_STOP_PENDING==ssStatus.dwCurrentState)
					{
						_tprintf(TEXT("."));
						Sleep(1000);
					}
					else
						break;
				}
				if(SERVICE_STOPPED==ssStatus.dwCurrentState)
					_tprintf(TEXT("\n %s stopped. \n"),TEXT(SZAPPNAME));
				else
					_tprintf(TEXT("\n %s failed to stopp. \n"),TEXT(SZAPPNAME));
			}
			//删除已安装的服务程序安装
			if(DeleteService(schService))
				_tprintf(TEXT("%s removed. \n"),TEXT(SZAPPNAME));
			else
				_tprintf(TEXT("DeleteService failed - %s. \n"), GetLastError());
			CloseServiceHandle(schService);
		}
		else
			_tprintf(TEXT("OpenService failed - %s \n"),GetLastError());
		CloseServiceHandle(schSCManager);
	}
	else
		_tprintf(TEXT("OpenSCManager failed - %s \n"),GetLastError());
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值