CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  VCL组件开发及应用

如何编写WindowsNT服务程序?

楼主hotheartman()2000-09-27 13:40:00 在 Delphi / VCL组件开发及应用 提问

如何编写(及配置注册表)可在控制面板-服务中启动、停止的程序?请指点关键步骤,或说明何处有相关资料。 问题点数:50、回复次数:2Top

1 楼huangshen()回复于 2000-09-27 14:04:00 得分 30

New   ---->   Service   Application  
  为Service的OnStart,   OnStop等方法添加相关代码(注意:处理完事件后需设置标志位,例如处理完OnStart事件后,设置Started:=true)。编译程序,在Dos方式下执行:程?骺穧?蛎?/install安装该Service,然后用   net   start   服务名(注意:是服务名而不是程序名),启动Service,也可以在服务管理器中找到相关的服务,然后启动之。同理可以停止/反安装该Service。  
   
  需注意并非所有控制都是线程安全的,所以在制作NT   Service时要特别小心。,   New   ---->   Service   Application  
  为Service的OnStart,   OnStop等方法添加相关代码(注意:处理完事件后需设置标志位,例如处理完OnStart事件后,设置Started:=true)。编译程序,在Dos方式下执行:程?骺穧?蛎?/install安装该Service,然后用   net   start   服务名(注意:是服务名而不是程序名),启动Service,也可以在服务管理器中找到相关的服务,然后启动之。同理可以停止/反安装该Service。  
   
  需注意并非所有控制都是线程安全的,所以在制作NT   Service时要特别小心。Top

2 楼playpcgame(修罗王)回复于 2000-09-27 15:01:00 得分 20

Windows   NT   下Service   的   编   程    
  ----   Windows   NT   Server   提   供   多   种   功   能   强   大   的   服   务(Service),   例   如FTP,WWW   或   远   程   登   录   服   务,   另   外   常   用   的   数   据   库   服   务   器   也   是   以Service   的   形   式   存   在   于NT   Server   上   的,   如Sybase   SQL   Server   For   NT。Service   一   般   在NT   启   动   时   自   动   启   动,   在NT   关   机   时   停   止。   但   是   有   时   用   户   可   能   想   手   工   启   动﹑   暂   停﹑   停   止   某   项Service,   这   就   需   要   在   控   制   面   板   中   进   行   配   置,   对   于   不   太   熟   悉NT   的   用   户   来   说   比   较   困   难;   对   于   软   件   开   发   人   员,   有   时   需   要   在   软   件   中   访   问   和   操   作   某   项Service,   甚   至   可   能   需   要   开   发   新Service   的   提   供   给   用   户   使   用。   上   面   两   种   情   况   都   可   以   通   过   对Service   的   编   程   来   解   决。   对Service   的   编   程   涉   及   到NT   的   内   核,   比   较   复   杂   且   相   关   资   料   较   少,   给   软   件   开   发   人   员   带   来   很   多   困   难,   笔   者   通   过   对Windows   NT   的API   的   分   析   找   到   了   相   应   的   编   程   方   法,   再   此   介   绍   给   大   家。    
  ----   在Windows   NT   下,   各   种Service   都   存   在service   control   manager   database   中,   因   此   我   们   可   以   通   过   对service   control   manager   database   进   行   操   作   来   实   现   对Service   的   编   程。   下   面   介   绍   常   用   的   函   数:    
        1:SC_HANDLE     OpenSCManager  
              (LPCTSTR     lpszMachineName,  
              LPCTSTR       lpszDatabaseName,  
              DWORD         fdwDesiredAccess);  
  ----   OpenSCManager   函   数   打   开   指   定   计   算   机   上   的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  
            //允许获取service   control   manager   database的封锁信息  
  ----   函   数   返   回   值:   函   数   执   行   成   功   则   返   回   一   个   指   向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中存放返回的服务状态信息,结构如下    
  typedef   struct   _SERVICE_STATUS   {      
  DWORD   dwServiceType;  
                              //服务类型  
  DWORD   dwCurrentState;  
                              //当前状态  
  DWORD   dwControlsAccepted;  
                      //服务可接受的控制码  
  DWORD   dwWin32ExitCode;    
                      //Win32出错代码  
  DWORD   dwServiceSpecificExitCode;  
          //服务出错代码  
  DWORD   dwCheckPoint;  
            //用于跟踪服务长时间操作  
  DWORD   dwWaitHint;  
            //服务某一操作的最大允许时间,以毫秒为单位  
  }   SERVICE_STATUS,   *LPSERVICE_STATUS;    
  ----   函   数   返   回   值:   函   数   执   行   成   功   则   返   回True,   失   败   则   返   回False。    
          4:BOOL   StartService(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   函   数   向Win32   service   发   送   控   制   码。    
  ----   其   中   参   数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。    
  unit   Unit1;  
   
  interface  
   
  uses  
      Windows,Messages,   SysUtils,   Classes,  
      Graphics,Controls,Forms,    
        Dialogs,StdCtrls,Winsvc;  
   
  type  
      TForm1   =   class(TForm)  
          ListBox1:   TlistBox;  
          Button1:   Tbutton;  
          Button2:   Tbutton;  
          Button3:   Tbutton;  
          procedure   Button1Click(Sender:   TObject);  
          procedure   Button3Click(Sender:   TObject);  
          procedure   Button2Click(Sender:   TObject);  
  procedure   FormClose  
  (Sender:   TObject;   var   Action:   TCloseAction);  
   
      private  
          {   Private   declarations   }  
      public  
      hscmanager,hService:SC_HANDLE;  
      returnstatus:TServiceStatus;  
          {   Public   declarations   }  
      end;  
   
  var  
      Form1:   TForm1;  
   
  implementation  
   
  {$R   *.DFM}  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  var  
  BytesNeeded,serviceReturned,resumeHandle:Dword;  
  returnflag:Bool;  
  lpservice:Array[0..100]   of     TEnumServiceStatus;  
  service:TEnumServiceStatus;  
  i,bytes:Dword;  
  begin  
  ListBox1.Items.Clear;  
  returnflag:=false;  
  resumeHandle:=0;  
  hscmanager:=OpenSCManager(nil,nil,SC_MANAGER  
  _ENUMERATE_SERVICE);//   打开  
    service   control   manager   database  
  if     hscmanager<0   then  
          Begin  
  showmessage('无法打开  
  service   control   manager   database');  
          exit;  
          End;    
  returnflag:=EnumServicesStatus(hscmanager,  
  SERVICE_DRIVER,SERVICE_ACTIVE,  
    service,sizeof(service),BytesNeeded,serviceR  
  eturned,resumeHandle);  
  //枚举Service  
  if   (returnflag=false)   and   (GetLastError()  
  =ERROR_MORE_DATA)   then  
          begin  
          bytes:=BytesNeeded+sizeof(TEnumServiceStatus);  
  EnumServicesStatus(hscmanager,SERVICE_  
  DRIVER,SERVICE_ACTIVE,  
  lpservice[0],bytes,BytesNeeded,service  
  Returned,resumeHandle);  
          for   i:=0   to   serviceReturned-1   do  
                  begin  
                  ListBox1.Items.Add(lpservice[i].lpServiceName);  
                  end;  
          end;  
  end;  
   
  procedure   TForm1.Button2Click(Sender:   TObject);  
  var  
  i:integer;  
  lpServiceArgVectors:Pchar;  
  begin  
  lpServiceArgVectors:=nil;  
  for   i   :=0   to   (ListBox1.Items.Count-1)   do  
        if   ListBox1.Selected[i]   then  
            begin  
            hService:=OpenService(hscmanager,Pchar  
  (ListBox1.Items[i]),SERVICE_ALL_ACCESS);  
  //打开该Service  
            if   hService<0   then  
                  begin  
                  showmessage('无法打开该Service');  
                  exit;  
                  end;  
                  QueryServiceStatus(hService,returnstatus);  
  //查看该Service的状态  
            if   returnstatus.dwCurrentState=SERVICE_STOPPED  
        then   //如果该Service已停止则启动它  
                  StartService(hService,0,lpServiceArgVectors);  
            CloseServiceHandle(hService);//关闭该Service  
          end;  
  end;  
   
   
  procedure   TForm1.Button3Click(Sender:   TObject);  
  var  
  i:integer;  
  begin  
    for   i   :=0   to   (ListBox1.Items.Count-1)   do  
        if   ListBox1.Selected[i]   then  
            begin  
            hService:=OpenService(hscmanager,Pchar  
  (ListBox1.Items[i]),SERVICE_ALL_ACCESS);  
    //打开该Service  
            if   hService<0   then  
                  begin  
                  showmessage('无法打开该Service');  
                  exit;  
                  end;  
                  QueryServiceStatus(hService,returnstatus);  
    查看该Service的状态  
            if   returnstatus.dwCurrentState=  
  SERVICE_RUNNING   then  
  //如果该Service正在运行则停止它  
                  ControlService(hService,SERVICE  
  _CONTROL_STOP,returnstatus);  
    CloseServiceHandle(hService);//关闭该Service  
          end;  
  end;  
   
   
  procedure   TForm1.FormClose  
  (Sender:   TObject;   var   Action:   TCloseAction);  
  begin  
  CloseServiceHandle(hscmanager);  
  //关闭service   control   manager   database  
  End;  
   
  end.  
   
  Top

相关问题

  • 怎样编写Winnt的服务程序?
  • 服务器方程序用socket api编写,客户方的程序能否用csocket类来编写,请指教!!
  • 怎样用VC编写winNT或win2000server的服务程序
  • 请教如何用JAVA编写服务程序
  • 怎样编写FTP服务器端程序?源码?
  • 如何编写虚拟internet服务器程序
  • 请教如何编写客户机/服务器程序
  • 有谁编写过NT的服务程序?
  • 如何用delphi编写服务器端的监听程序
  • 谁会用delphi编写ftp服务端程序???

关键词

  • win32
  • service
  • nt
  • 代码
  • 函
  • 服务
  • sc
  • lpservice
  • 程
  • fdwdesiredaccess

得分解答快速导航

  • 帖主:hotheartman
  • huangshen
  • playpcgame

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo