• WindowsNT下Service的编程


    WindowsNT下Service的编程

    ----此例中原程序使用Delphi编制,老妖将之改成CB版。:D

    ----WindowsNTServer提供多种功能强大的服务(Service),例如FTP,WWW或远程登录服务,另外常用的数据库服务器也是以Service的形式存在于NTServer上的,如Sybase SQLServer For NT。Service一般在NT启动时自动启动,在NT关机时停止。但是有时用户可能想手工启动、暂停、停止某项Service,这就需要在控制面板中进行配置,对于不太熟悉NT的用户来说比较困难;对于软件开发人员,有时需要在软件中访问和操作某项Service,甚至可能需要开发新Service的提供给用户使用。上面两种情况都可以通过对Service的编程来解决。对Service的编程涉及到NT的内核,比较复杂且相关资料较少,给软件开发人员带来很多困难,笔者通过对WindowsNT的API的分析找到了相应的编程方法,再此介绍给大家。

    ----在WindowsNT下,各种Service都存在service control manager database中,因此我们可以通过对service control manager database进行操作来实现对Service的编程。下面介绍常用的函数:

    1:SC_HANDLE OpenSCManager(LPCTSTR lpszMachineName,LPCTSTR lpszDatabaseName,DWORD fdwDesiredAccess);

    ----Open SCManager 函数打开指定计算机上的service control manager database。其中参数lpszMachineName指定计算机名,若为空则指定为本机。参数lpszDatabaseName指定要打开的service control manager database,默认为空。

    ----参数fdwDesiredAccess指定操作的权限,可以为下面取值之一

    SC_MANAGER_ALL_ACCESS        //所有权限
    SC_MANAGER_CONNECT           //允许连接service control manager
    SC_MANAGER_CREATE_SERVICE    //允许创建服务对象并把它加入service control manager database
    SC_MANAGER_ENUMERATE_SERVICE //允许枚举service control manager database中的服务
    SC_MANAGER_LOCK              //允许锁住service control manager database
    SC_MANAGER_QUERY_LOCK_STATUS //允许获取servicecontrolmanagerdatabase的封锁信息

    ----函数返回值:函数执行成功则返回一个指向service control manager database的句柄,失败则返回NULL。

    2:SC_HANDLE OpenService(SC_HANDLE schSCManager,LPCTSTR lpszServiceName,DWORD fdwDesiredAccess);

    ----OpenService函数打开指定的Service。
    ----其中参数schSCManager是指向service control manager database的句柄,由OpenSCManager函数返回。
    ----参数lpszServiceName要打开的服务的名字,注意大小写。
    ----参数fdwDesiredAccess指定操作的权限,可以为下面取值之一

    SERVICE_ALL_ACCESS            //所有权限
    SERVICE_CHANGE_CONFIG         //允许更改服务的配置
    SERVICE_ENUMERATE_DEPENDENTS  //允许获取依赖于该服务的其他服务
    SERVICE_INTERROGATE            //允许立即获取服务状态
    SERVICE_PAUSE_CONTINUE        //允许暂停和唤醒服务
    SERVICE_QUERY_CONFIG           //允许获取服务配置
    SERVICE_QUERY_STATU            //允许通过访问service control manager获取服务状态
    SERVICE_START                  //允许启动服务
    SERVICE_STOP                   //允许停止服务
    SERVICE_USER_DEFINE_CONTROL    //允许用户指定特殊的服务控制码


    ----函数返回值:函数执行成功则返回指向某项服务的句柄,失败则返回NULL。

    3:BOOL QueryServiceStatus(SC_HANDLE schService,LPSERVICE_STATUS lpssServiceStatus);

    ----QueryServiceStatus函数返回指定服务的当前状态。
    ----其中参数schService是指向某项服务的句柄,由OpenService函数返回,且必须SERVICE_QUERY_STATUS的权限。
    ----参数lpssServiceStatus中存放返回的服务状态信息,结构如下
    typedefstruct_SERVICE_STATUS
    {
        DWORD dwServiceType;        //服务类型
        DWORD dwCurrentState;        //当前状态
        DWORD dwControlsAccepted;    //服务可接受的控制码
        DWORD dwWin32ExitCode;        //Win32出错代码
        DWORD dwServiceSpecificExitCode;//服务出错代码
        DWORD dwCheckPoint;            //用于跟踪服务长时间操作
        DWORD dwWaitHint;             //服务某一操作的最大允许时间,以毫秒为单位
    }SERVICE_STATUS,*LPSERVICE_STATUS;

    ----函数返回值:函数执行成功则返回True,失败则返回False。

    4:BOOLStartService(SC_HANDLE schService,DWORD dwNumServiceArgs,LPCTSTR * lpszServiceArgs);

    ----StartService函数启动指定的服务。
    ----其中参数schService是指向某项服务的句柄,由OpenService函数返回,且必须有SERVICE_START的权限。
    ----dwNumServiceArgs为启动服务所需的参数的个数。
    ----lpszServiceArgs为启动服务所需的参数。函数返回值:函数执行成功则返回True,失败则返回False。

    5:BOOL ControlService(SC_HANDLE hService,DWORD dwControl,LPSERVICE_STATUS lpServiceStatus);

    ----ControlService函数向Win32service发送控制码。
    ----其中参数hService是指向某项服务的句柄,由OpenService函数返回。
    ----参数dwControl为控制码,常用的有
        SERVICE_CONTROL_STOP     //停止服务
        SERVICE_CONTROL_PAUSE    //暂停服务
        SERVICE_CONTROL_CONTINUE    //唤醒暂停的服务
        SERVICE_CONTROL_INTERROGATE//刷新某服务的状态
    ----参数lpServiceStatus指向SERVICE_STATUS结构,用于存放该服务最新的状态信息。
    ----函数返回值:函数执行成功则返回True,失败则返回False。

    6:BOOL EnumServicesStatus(SC_HANDLE hSCManager,DWORD dwServiceType,DWORD dwServiceState,LPENUM_SERVICE_STATUS lpServices,DWORD cbBufSize,LPDWORD pcbBytesNeeded,LPDWORD lpServicesReturned,LPDWORD lpResumeHandle);

    ----EnumServicesStatus函数用于枚举NT下存在的Service。
    ----其中参数hSCManager是指向service control manager database的句柄,由OpenSCManager函数返回,且必须有SC_MANAGER_ENUMERATE_SERVICE的权限。
    ----参数dwServiceType指定按服务的类型枚举。
    ----参数dwServiceState指定按服务的状态枚举。
    ----参数lpServices指向ENUM_SERVICE_STATUS结构,用于存放返回的服务的名字和状态信息。
    ----参数cbBufSize返回参数lpServices的长度,以字节为单位。
    ----参数pcbBytesNeeded返回获取剩余的Service所需字节的个数。
    ----参数lpServicesReturned返回服务的个数。
    ----参数lpResumeHandle,当第一次调用时该参数为0,当该函数再次被调用以获取另外的信息时,该参数表示下一个被读的Service。
    ----函数返回值:函数执行成功则返回True,失败则返回False。
    ----值得注意的是通常情况下该函数返回的结果为FALSE,我们可以调用GetLastError()来获取进一步信息。因为一台机器上有多种服务存在,所以GetLastError()应为ERROR_MORE_DATA,此时应再次调用EnumServicesStatus函数以获取正确的Service列表。

    ----下面有一个用Delphi编的一个程序例子,用其他开发工具如VC,VB也可实现。程序运行时,单击按钮Button1枚举NT中的Service并显示在列表框ListBox1中。在ListBox1选中某个Service,单击按钮Button2则启动该Service,单击按钮Button3则停止该Service。

    首先在Unit1.hpp中添加
    #include <winsvc.hpp>
    然后在Class Form1的Private中添加

    SC_HANDLE hscmanager,hService;
    TServiceStatus returnstatus;

    以下是Unit1.cpp的内容:
    /**************************************************************************
    * 枚举NT系统当服务并启动或终止之。
    * * 2002.8.9
    ****************************************************************************/

    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
    DWORD BytesNeeded,serviceReturned,resumeHandle;
    bool returnflag;
    TEnumServiceStatus lpservice[100];
    TEnumServiceStatus service;
    DWORD i,bytes;

    ListBox1->Items->Clear();
    returnflag=false;
    resumeHandle=0;
    hscmanager=OpenSCManager(NULL,NULL,SC_MANAGER_ENUMERATE_SERVICE);//打开service control manager database
    if (hscmanager<0)
      {
      ShowMessage("无法打开service control manager database");
      return;
      }
    returnflag=EnumServicesStatus(hscmanager,SERVICE_DRIVER,SERVICE_ACTIVE,&service,sizeof(service),&BytesNeeded,&serviceReturned,&resumeHandle);//枚举Service
    if(!returnflag&&GetLastError()==ERROR_MORE_DATA)
      {
      bytes=BytesNeeded+sizeof(TEnumServiceStatus);
      EnumServicesStatus(hscmanager,SERVICE_DRIVER,SERVICE_ACTIVE,&lpservice[0],bytes,&BytesNeeded,&serviceReturned,&resumeHandle);
      for(i=0;i<serviceReturned-1;i++)
        {
        ListBox1->Items->Add(lpservice[i].lpServiceName);
        }
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button2Click(TObject *Sender)
    {
    int i;
    for(i=0;i<ListBox1->Items->Count;i++)
      {
      if(ListBox1->Selected[i])
        {
        hService=OpenService(hscmanager,PChar(ListBox1->Items->Strings[i].c_str()),SERVICE_ALL_ACCESS);//打开该Service
        if(hService<0)
          {
          ShowMessage("无法打开该服务!");
          return;
          }
        QueryServiceStatus(hService,&returnstatus);//查看该Service的状态
        if(returnstatus.dwCurrentState==SERVICE_STOPPED)//如果该Service已停止则启动它
        //SERVICE_STOPPED==1,SERVICE_RUNNING==4  老妖注。
          {
          if(StartService(hService,0,NULL))
            ShowMessage("启动成功!");
          else
            ShowMessage("无法启动该服务!");
          }
        CloseServiceHandle(hService);//关闭该Service
        }
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button3Click(TObject *Sender)
    {
    int i;

    for(i=0;i<ListBox1->Items->Count;i++)
      {
      if(ListBox1->Selected[i])
        {
        hService=OpenService(hscmanager,PChar(ListBox1->Items->Strings[i].c_str()),SERVICE_ALL_ACCESS);//打开该Service
        if(hService<0)
          {
          ShowMessage("无法打开该Service");
          return;
          }
        QueryServiceStatus(hService,&returnstatus);//查看该Service的状态
        if(returnstatus.dwCurrentState==SERVICE_RUNNING) //如果该Service正在运行则停止它
          {
          if(ControlService(hService,SERVICE_CONTROL_STOP,&returnstatus))
            ShowMessage("成功停止!");
          else
            ShowMessage("无法停止该服务!");
          }
        CloseServiceHandle(hService);//关闭该Service
        }
      }
    }
    //---------------------------------------------------------------------------
    void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
    {
    CloseServiceHandle(hscmanager);//关闭service control manager database        
    }
    //---------------------------------------------------------------------------

  • 相关阅读:
    Spring总结四:IOC和DI 注解方式
    Spring总结二:IOC(控制反转)xml方式
    Spring总结一:Srping快速入门
    TCP UDP HTTP 的关系和区别
    sql 一些偶尔会用到的写法和函数 不定时更新
    AngularJS分层开发
    AngularJS入门
    url和uri的区别
    MyBatis总结八:缓存介绍(一级缓存,二级缓存)
    Javascript 中 == 与=== 对比
  • 原文地址:https://www.cnblogs.com/cpprun/p/2660754.html
Copyright © 2020-2023  润新知