Πέμπτη 9 Μαΐου 2013

Handling Windows services (Starting / stopping)

Bellow are two function that handle Windows services (Start / stop)
//START A SERVICE//
uses WinSvc;
// return TRUE if service succesfully Started
// aMachineName:
//   machine name, ie: \\DESKTOP, if empty = local machine
// aServiceName
//   service name, ie:  W32Time

function ServiceStart(aMachineName,aServiceName: string): boolean;
var
  schm,
  schs: SC_Handle;
  ss: TServiceStatus;
  psTemp: PChar;
  dwChkP: DWord;
begin
  ss.dwCurrentState := -1;
  schm := OpenSCManager(PChar(aMachineName),nil, SC_MANAGER_CONNECT);
  if (schm > 0) then
  begin
    schs := OpenService(schm,PChar(aServiceName),SERVICE_START or SERVICE_QUERY_STATUS);
    if (schs > 0) then
    begin
      psTemp := nil;
      if (StartService(schs,0, psTemp)) then
      begin
        if (QueryServiceStatus(schs,ss)) then
        begin
          while (SERVICE_RUNNING <> ss.dwCurrentState) do
          begin
            dwChkP := ss.dwCheckPoint;
            Sleep(ss.dwWaitHint);
            if (not QueryServiceStatus(schs,ss)) then
            begin
              break;
            end;
            if (ss.dwCheckPoint <dwChkP) then
            begin
              break;
            end;
          end;
        end;
      end;
      CloseServiceHandle(schs);
    end;
    CloseServiceHandle(schm);
  end;
  Result := SERVICE_RUNNING = ss.dwCurrentState;
end;


//STOP A SERVICE// 

// return TRUE if service succesfully STOPPED
// aMachineName:
//   machine name, ie: \\DESKTOP, if empty = local machine
// aServiceName
//   service name, ie:  W32Time


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

1 σχόλιο: