Solved

Stop Start NT Service from Delphi App

Posted on 2004-10-27
224 Views
Last Modified: 2010-04-05
I wrote a the following in Delphi 5
1) NT Service.
2) Control Panel application that contains one Delphi form.
    I need to stop and start my NT Service from the Control Panel's form.

How does one stop and start a NT Service from a delphi Application ?
Applications to be deployed to Win2K and XP platforms.

Thanks
0
Question by:xy15973
    2 Comments
     
    LVL 17

    Accepted Solution

    by:
    Hi,

    Here it is:

    uses WinSvc;

    function ServiceStart(sMachine, sService: String) : Boolean;
    var
      schm,   schs: SC_Handle;
      ss: TServiceStatus;
      psTemp: PChar;
      dwChkP: DWord;
    begin
      ss.dwCurrentState := 0;
     schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT);
      if (schm>0) then
      begin
       schs := OpenService(schm, PChar(sService), SERVICE_START or SERVICE_QUERY_STATUS);
        if (schs>0) then
       begin
         psTemp := nil;
          if (StartService(schs, 0, psTemp)) then
            if (QueryServiceStatus(schs, ss)) then
             while (SERVICE_RUNNING<>ss.dwCurrentState) do
              begin
               dwChkP := ss.dwCheckPoint;
                Sleep(ss.dwWaitHint);
               if (not QueryServiceStatus(schs, ss)) then    
                Break;
                if ss.dwCheckPoint <> 0 then  
                  Break;
              end;
          CloseServiceHandle(schs);
        end;
       CloseServiceHandle(schm);
      end;
     Result := SERVICE_RUNNING=ss.dwCurrentState;
    end;

    function ServiceStop(sMachine, sService: String) : Boolean;
    var   schm,   schs: SC_Handle;
      ss: TServiceStatus;
     dwChkP: DWord;
    begin  
    schm := OpenSCManager(PChar(sMachine), nil, SC_MANAGER_CONNECT);
     if (schm>0) then   begin
        schs := OpenService(schm, PChar(sService), SERVICE_STOP or SERVICE_QUERY_STATUS);
        if (schs>0) then
        begin
         if (ControlService(schs, SERVICE_CONTROL_STOP, ss)) then
            if (QueryServiceStatus(schs, ss)) then
             while (SERVICE_STOPPED<>ss.dwCurrentState) do
             begin  
              dwChkP := ss.dwCheckPoint;
                Sleep(ss.dwWaitHint);
                if (not QueryServiceStatus(schs, ss)) then
                  Break;
                if ss.dwCheckPoint <> 0 then
                  Break;
              end;
          CloseServiceHandle(schs);
        end;
       CloseServiceHandle(schm);
      end;
      Result := SERVICE_STOPPED=ss.dwCurrentState;
    end;

    // usage:
    procedure TForm1.Button1Click(Sender: TObject);
    begin
    ServiceStart('','Alerter');
    //ServiceStart('\\computername','Alerter');
    end;

    procedure TForm1.Button2Click(Sender: TObject);
    begin
    ServiceStop('','Alerter');
    end;

    Regards, Geo
    0
     

    Expert Comment

    by:krypto2000
    I've maked this just two days before ;-)

    There is my solution :

    uses
       WinSvc, SvcMgr;

    const
       SERVICE_NAME = 'myService';

    { start / pause / stop service }
    procedure setServiceStatus(serviceName:string; serviceStatus:cardinal);
    var svc,
        svcManager : SC_HANDLE;
        status     : TServiceStatus;
    begin
       svcManager := OpenSCManager(nil,nil,SC_MANAGER_ALL_ACCESS);

       if serviceStatus = SERVICE_RUNNING then
          if currentServiceStatus = SERVICE_PAUSED then
             try
             svc := OpenService(svcManager,PChar(serviceName),SERVICE_PAUSE_CONTINUE);
             ControlService(svc,SERVICE_CONTROL_CONTINUE,status);
             finally
               CloseServiceHandle(svc);
             end
          else
             try
               svc := OpenService(svcManager,PChar(serviceName),SERVICE_START);
               StartService(svc,0,Pchar(nil^));
             finally
               CloseServiceHandle(svc);
             end;

       if serviceStatus = SERVICE_PAUSED then
          try
            svc := OpenService(svcManager,PChar(serviceName),SERVICE_PAUSE_CONTINUE);
            ControlService(svc,SERVICE_CONTROL_PAUSE,status);
          finally
            CloseServiceHandle(svc);
          end;

       if serviceStatus = SERVICE_STOPPED then
          try
            svc := OpenService(svcManager,PChar(serviceName),SERVICE_STOP);
            ControlService(svc,SERVICE_CONTROL_STOP,status);
          finally
            CloseServiceHandle(svc);
          end;

       CloseServiceHandle(svcManager);
    end;

    procedure TfrmMain.btnStartClick(Sender: TObject);
    begin
       setServiceStatus(SERVICE_NAME,SERVICE_RUNNING);
    end;

    procedure TfrmMain.btnPauseClick(Sender: TObject);
    begin
       setServiceStatus(SERVICE_NAME,SERVICE_PAUSED);
    end;

    procedure TfrmMain.btnStopClick(Sender: TObject);
    begin
       setServiceStatus(SERVICE_NAME,SERVICE_STOPPED);
    end;

    and there is another function to get the service status

    { return service state }
    function getServiceStatus(serviceName:string): cardinal;
    var svc,
        svcManager : SC_HANDLE;
        status     : TServiceStatus;
    begin
       svcManager := OpenSCManager(nil,nil,GENERIC_READ);
       try
         svc := OpenService(svcManager,PChar(serviceName),SERVICE_QUERY_STATUS);
         if svc <> 0 then
           try
             if QueryServiceStatus(svc,status) then result := status.dwCurrentState;
           finally
             CloseServiceHandle(svc);
           end;
       finally
         CloseServiceHandle(svcManager);
       end;
    end;

    use --> currentServiceStatus := GetServiceStatus(SERVICE_NAME);

    I hope the help you ;-)
    0

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone. Privacy Policy Terms of Use

    Featured Post

    IT Security CISA, CISSP & CISM Certification

    Master the advanced techniques required to protect network resources from external threats with the IT Cyber Security bundle. Built around industry best-practice guidelines, the IT Cyber Security bundle consists of three in-depth courses.

    A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
    Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
    In this sixth video of the Xpdf series, we discuss and demonstrate the PDFtoPNG utility, which converts a multi-page PDF file to separate color, grayscale, or monochrome PNG files, creating one PNG file for each page in the PDF. It does this via a c…
    Internet Business Fax to Email Made Easy - With eFax Corporate (http://www.enterprise.efax.com), you'll receive a dedicated online fax number, which is used the same way as a typical analog fax number. You'll receive secure faxes in your email, fr…

    875 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    11 Experts available now in Live!

    Get 1:1 Help Now