Stop Start NT Service from Delphi App

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
xy15973Asked:
Who is Participating?
 
geobulConnect With a Mentor Commented:
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
 
krypto2000Commented:
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
All Courses

From novice to tech pro — start learning today.