关于windows服务的编程方法.docx

上传人:b****4 文档编号:12316388 上传时间:2023-04-18 格式:DOCX 页数:28 大小:20.64KB
下载 相关 举报
关于windows服务的编程方法.docx_第1页
第1页 / 共28页
关于windows服务的编程方法.docx_第2页
第2页 / 共28页
关于windows服务的编程方法.docx_第3页
第3页 / 共28页
关于windows服务的编程方法.docx_第4页
第4页 / 共28页
关于windows服务的编程方法.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

关于windows服务的编程方法.docx

《关于windows服务的编程方法.docx》由会员分享,可在线阅读,更多相关《关于windows服务的编程方法.docx(28页珍藏版)》请在冰豆网上搜索。

关于windows服务的编程方法.docx

关于windows服务的编程方法

关于windows服务的编程方法

windows服务有两种,一种是驱动服务程序,另外一种是win32服务程序,我们这里只谈win32服务程序,

查看win32服务程序,可以这样:

开始->运行->services.msc可以打开windows自带的服务程序控制程

序。

这个大家都应该很熟悉了吧。

下面来讲讲利用vc编程来对win32服务程序进行管理,包括创建、删除

已经对win32服务程序的运行状态进行管理。

在进入编程之前先要理解几样东西:

第一:

服务控制管理器servicecontrolmanager(SCM),SCM在系统启动的时候就会启动,其主要的

作用有以下几个方面:

1)维持了一张已安装的服务的数据表

2)根据策略在系统启动时启动服务或者在需要的时候启动服务

4)枚举已经安装的服务

4)维持了正在运行的服务的状态信息

5)向正在运行的服务发送控制信息

6)对服务数据库的锁定管理

SCM所维持的数据库可以在注册表中找到:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

SCM通过三类程序的方法来实现对服务的管理:

Serviceprogram、Serviceconfigurationprogram和

Servicecontrolprogram

ServiceProgram:

也就是被注册成服务的程序主体,他必须符合服务控制器(SCM)的接口规范,这样

才能被SCM控制(包括启动,停止等等),一个服务程序内可以包含一个服务或多个服务的执行代码,但

是它们都拥有固定的三个部分:

服务main函数,服务ServiceMain函数和服务ControlHandler函数。

服务main函数:

入口点函数,由于服务程序通常是以控制台的方式存在的,所以它们的入口点自然就是

main函数。

在服务控制管理器开始一个服务程序时,会等待StartServiceCtrlDispatcher函数的执行。

如果服务类型是SERVICE_WIN32_OWN_PROCESS就会立即调用StartServiceCtrlDispatcher函数的执行;如

果服务类型是SERVICE_WIN32_SHARE_PROCESS,通常在初始化所有服务之后再调用它。

StartServiceCtrlDispatcher这个函数的作用就是把服务入口点函数和SCM连接起来。

服务ServiceMain函数:

函数ServiceMain是服务的入口点。

在服务控制程序请求一个新的服务启动时,

服务控制管理器启动一个服务,并发送一个开始请求到控制调度程序,而后控制调度程序创建一个新线

程来执行ServiceMain函数。

ServiceMain须执行以下的任务:

调用RegisterServiceCtrlHandler函数注

册一个HandlerEx函数来向服务发送控制请求信息,返回值是服务状态句柄用来向服务控制管理器传送服

务状态。

初始化后调用SetServiceStatus函数设置服务状态为SERVICE_RUNNING。

最后,就是执行服务所

要完成的任务。

服务ControlHandler函数:

每个服务都有一个控制句柄HandlerEx函数。

它会在服务进程从服务控制程

序接收到一个控制请求时被控制调度程序所调用。

无论何时在HandlerEx函数被调用时,都要调用

SetServiceStatus函数向服务控制管理器报告它当前的状态。

在用户关闭系统时,所有的控制句柄都会

调用带有SERVICE_ACCEPT_SHUTDOW控制代码的SetServiceStatus函数来接收NSERVICE_CONTROL_SHUTDOWN

控制代码。

这里是一个Serviceprogram的例子:

实现的功能就是打开一个端口一直监听,连接上来之后,发送一串数据,然后关闭连接。

#include"Afxwin.h"

#include"windows.h"

#include"stdio.h"

#include"winsock2.h"

#pragmacomment(lib,"ws2_32")

HANDLEhMutex;

SERVICE_STATUS       ServiceStatus;

SERVICE_STATUS_HANDLEServiceStatusHandle;

//ServiceControlHandlerFunction

voidWINAPICmdControl(DWORDdwCode)

{

       switch(dwCode)

       {

       caseSERVICE_CONTROL_PAUSE:

               ServiceStatus.dwCurrentState=SERVICE_PAUSED;

               break;

       caseSERVICE_CONTROL_CONTINUE:

               ServiceStatus.dwCurrentState=SERVICE_RUNNING;

               break;

       caseSERVICE_CONTROL_STOP:

     

               WaitForSingleObject(hMutex,INFINITE);

               ServiceStatus.dwCurrentState =SERVICE_STOPPED;

               ServiceStatus.dwWin32ExitCode=0;

               ServiceStatus.dwCheckPoint   =0;

               ServiceStatus.dwWaitHint     =0;

               if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)

               {

                       printf("SetServiceStatusinCmdControlinSwitchError!

\n");

               }

               return;

       caseSERVICE_CONTROL_INTERROGATE:

               break;

       default:

               break;

       }

       if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)

       {

               printf("SetServiceStatusinCmdControloutSwitchError!

\n");

       }

       return;

}

listenPort()

{

       WSADATA             wsa;

   SOCKET              sServer;

   SOCKET              sClient;

       struct              sockaddr_insin;

       WSAStartup(MAKEWORD(2,2),&wsa);

       sServer=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);

       if(sServer==INVALID_SOCKET)

       {

               printf("SocketError!

\n");

               return-1;                                  

       }

       sin.sin_family          =AF_INET;

       sin.sin_port            =htons(20540);

       sin.sin_addr.S_un.S_addr=INADDR_ANY;

       if(bind(sServer,(conststructsockaddr*)&sin,sizeof(sin))==SOCKET_ERROR)

       {

               printf("BindError!

\n");

               return-1;

       }

       if(listen(sServer,5)==SOCKET_ERROR)  

       {

               printf("ListenError!

\n");

               return-1;

       }

       

       hMutex=CreateMutex(NULL,FALSE,NULL);

       if(hMutex==NULL)

       {

               printf("CreateMutexError!

\n");             

       }

 

   while

(1)

       {

               sClient=accept(sServer,NULL,NULL);

               

               send(sClient,"aa",sizeof("aa"),0);

               closesocket(sClient);

               

               Sleep(1000);

       }

   WSACleanup();

}

//ServiceServiceMainFunction

voidWINAPICmdStart(DWORDdwArgc,LPTSTR*lpArgv)

{

       

       ServiceStatus.dwServiceType            =SERVICE_WIN32;

       ServiceStatus.dwCurrentState           =SERVICE_START_PENDING;

       ServiceStatus.dwControlsAccepted       =SERVICE_ACCEPT_STOP

                                                   |SERVICE_ACCEPT_PAUSE_CONTINUE;

       ServiceStatus.dwServiceSpecificExitCode=0;

       ServiceStatus.dwWin32ExitCode          =0;

       ServiceStatus.dwCheckPoint             =0;

       ServiceStatus.dwWaitHint               =0;

       ServiceStatusHandle=RegisterServiceCtrlHandler("ntkrnl",CmdControl);//注册控制响应

程序

       if(ServiceStatusHandle==0)

       {

               printf("RegisterServiceCtrlHandlerError!

\n");

               return;

       }

       ServiceStatus.dwCurrentState=SERVICE_RUNNING;

       ServiceStatus.dwCheckPoint  =0;

       ServiceStatus.dwWaitHint    =0;

       

       if(SetServiceStatus(ServiceStatusHandle,&ServiceStatus)==0)

       {

               printf("SetServiceStatusinCmdStartError!

\n");

               return;

       }

       listenPort();

       

       return;

}

intmain()

{

       SERVICE_TABLE_ENTRYDispatchTable[]=

       {

               {"ntkrnl",CmdStart},

               {NULL   ,NULL   }

       };

       StartServiceCtrlDispatcher(DispatchTable);//注意:

CmdStart函数

       

       return0;

}

ServiceConfigurationPrograms:

其作用有两个方面,第一是创建、删除和枚举服务,第二是用来更

改或者查询已经安装的服务的信息。

完成这些任务可以直接操作注册表,但是最好还是使用SCM配置函

数。

SCM配置函数需要一个SCManger对象或者一个service对象,要获得这些对象可以使用OpenSCManager函

数,或者使用OpenService、CreateService获得service对象。

这里顺便就把ServiceControlPrograms说了,其实也就是包含一些函数可以控制服务的启动,停止,

相应的函数可以在msdn查询。

下面是一个创建服务的例子,首先使用OpenSCMagenager获得一个SCManger对象,然后使用

CreateService创建一个服务。

#include"windows.h"

#include"stdio.h"

#include"Winsvc.h"

#include"TCHAR.h"

#pragmacomment(lib,"Advapi32.lib")

intmain()

{

       

   SC_HANDLE               schManager;

       SC_HANDLE               schService;

       DWORD                   dwBytesNeeded;

       LPQUERY_SERVICE_CONFIG  lpServiceConfig     =NULL;

       LPSERVICE_DESCRIPTION   lpServiceDescription=NULL;

   SERVICE_STATUS          ServiceStatus;

       DWORD                   dwIndex;

       schManager=OpenSCManager

(NULL,NULL,SC_MANAGER_ALL_ACCESS);//SC_MANAGER_ALL_ACCESS);

       if(schManager==NULL)

       {

               printf("OpenschManagerError:

%d\n",GetLastError());

               returnFALSE;

       }

       SC_HANDLEhdlServ=CreateService(

                                       schManager,

                                       _T("test"),

                                       _T("test"),

                                       SC_MANAGER_ALL_ACCESS,

                                       0x00000010,

                                       3,

                                       //SERVICE_ALL_ACCESS,

                                       //SERVICE_WIN32_OWN_PROCESS,

                                       //SERVICE_DEMAND_START,

                                       SERVICE_ERROR_NORMAL,

                                       _T("d:

\\test.exe"),//这个就是由上面那个程序生成的

exe文件

                                       NULL,NULL,NULL,NULL,NULL

                                       );

       if(hdlServ==NULL)

       {

               DWORDgg=GetLastError();

               printf("error!

\n");

       }

       hdlServ=OpenService(schManager,_T

("test"),SC_MANAGER_ALL_ACCESS);//SERVICE_ALL_ACCESS);

       if(hdlServ==NULL)

       {

               printf("OpenSerivceerror\n");

       }

       /*

       if(!

DeleteService(hdlServ))

       {

               printf("deleteerror\n");

       }

       */

       //查看服务状态

       SERVICE_STATUSss;

   if(QueryServiceStatus(hdlServ,&ss)==FALSE)

       {

               printf("ErrorServiceStatus!

%d\n",GetLastError());

               returnFALSE;

       }

       //如果服务已经启动,则退出

       if(ss.dwCurrentState==SERVICE_RUNNING)

               returnTRUE;

       //启动服务

   StartService(hdlServ,0,NULL);   

       Sleep(1000);

       //查看服务状态

   if(QueryServiceStatus(hdlServ,&ss)==FALSE)

       {

               printf("ErrorServiceStatus!

%d\n",GetLastError());

               returnFALSE;

       }

       if(ss.dwCurrentState!

=SERVICE_RUNNING)

       {

               printf("ErrorinStartingService!

%d\n",GetLastError());

               CloseHandle(hdlServ);

               returnFALSE;

       }

       printf("\nend\n");

       return0;

}

最后,再举一个例子。

ServiceAll()枚举所有的服务,并打印出来

ServiceInformation(char*szServiceName)查询特定服务的具体信息

#include"windows.h"

#include"stdio.h"

#include"Winsvc.h"

#include"TCHAR.h"

#pragmacomment(lib,"Advapi32.lib")

BOOL ServiceAll()

{

   SC_HANDLE  schManager;

       DWORD      dwServiceType;

       DWORD      dwServiceState;

       DWORD      dwIndex;

       DWORD      cbBufSize;

       DWORD      ResumeHandle;

       DWORD      cbBytesNeeded;

       DWORD      ServicesReturned;

       ENUM_SERVICE_STATUS  EnumStatus[512];

       schManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);

       if(schManager==NULL)

       {

               printf("OpenschManagerError:

%d\n",GetLastError());

               returnFALS

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > PPT模板 > 商务科技

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1