windows 服务程序学习心得

来源:互联网 发布:全球贸易数据库是什么 编辑:程序博客网 时间:2024/06/06 12:11

         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."));elseAddToMessageLog(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_HANDLEschService;SC_HANDLEschSCManager;//打开服务管理数据库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);}elsebreak;}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());}