Icon View Thread

The following is the text of the current message along with any replies.
Messages 1 to 4 of 4 total
Thread Detecting EDBSRVR open in Win 7
Thu, Apr 8 2010 9:43 AMPermanent Link

Edward Jones

National Veterinary Services Limited

During my installation app I check whether the Elevate Server is running or not so I can close it down before upgrading it. In Win XP I do this by enumerating through the available windows looking for "ElevateDB Server" which works fine (even if it is started as a service), however, in Windows 7 the Elevate Server doesn't appear in the enumerated list when started as a service.

Is there any other way I can detect whether or not the Elevate Server is running as a service under Win 7?


Regards

Edward Jones
Thu, Apr 8 2010 11:09 AMPermanent Link

Edward Jones

National Veterinary Services Limited

Update: I have done it... The answer is to use the Service Control Manager and the OpenService API call... this works in both XP and Win 7 so all is good (and a lot neater than enumerating through window lists!!).

Regards

Edward Jones
Thu, Apr 8 2010 5:43 PMPermanent Link

Steve Gill

Avatar

Hi Edward,

> Update: I have done it... The answer is to use the Service Control Manager and the
> OpenService API call... this works in both XP and Win 7 so all is good (and a lot
> neater than enumerating through window lists!!).

If you don't mind sharing your code I'd be very interested to see how it's done.

Regards,

Steve
Fri, Apr 9 2010 4:02 AMPermanent Link

Edward Jones

National Veterinary Services Limited

Of course, no problem. I adapted the code from http://www.chami.com/tips/delphi/031598D.html and here it is, enjoy! -

unit ServicesTestUnit;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, WinSvc, StdCtrls;

type
 TServiceTestForm = class(TForm)
   btnStartService: TButton;
   btnStopService: TButton;
   btnQueryService: TButton;
   procedure btnStartServiceClick(Sender: TObject);
   procedure btnStopServiceClick(Sender: TObject);
   procedure btnQueryServiceClick(Sender: TObject);
 private
   { Private declarations }
   function ServiceStart(sMachine,sService :string):boolean;
   function ServiceStop(sMachine,sService :string ):boolean;
   procedure QueryService(sMachine,sService :string);
 public
   { Public declarations }
 end;

var
 ServiceTestForm: TServiceTestForm;

implementation

{$R *.dfm}

procedure TServiceTestForm.btnStartServiceClick(Sender: TObject);
begin
 Screen.Cursor :=crHourGlass;
 if ServiceStart('','EDBSRVR') then
   MessageDlg('Service started', mtInformation, [mbOk],0)
 else
   MessageDlg('Service not started', mtInformation, [mbOk],0);
 Screen.Cursor :=crDefault;
end;

//adapted from http://www.chami.com/tips/delphi/031598D.html
function TServiceTestForm.ServiceStart(sMachine,sService :string ):boolean;
var
 schm,   // service control manager handle
 schs: SC_Handle; // service handle
 ss: TServiceStatus;   // service status
 psTemp :PChar;
 dwChkP :DWord;   // check point
begin
 // connect to the service control manager
 schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);

 // if successful...
 if(schm > 0)then
 begin
   // open a handle to the specified service
   // we want to start the service and query service status
   schs := OpenService(schm,PChar(sService),SERVICE_START or SERVICE_QUERY_STATUS);

   // if successful...
   if(schs > 0)then
   begin
     psTemp := Nil;
     if(StartService(schs, 0, psTemp))then
     begin
       // check status
       if(QueryServiceStatus(schs, ss))then
       begin
         while(SERVICE_RUNNING <> ss.dwCurrentState)do
         begin
           // dwCheckPoint contains a value that the service increments periodically to report its progress
           // during a lengthy operation.
           // save current value
           dwChkP := ss.dwCheckPoint;

           // wait a bit before checking status again dwWaitHint is the estimated amount of time the calling program
           // should wait before calling QueryServiceStatus() again
           // idle events should be
           // handled here...
           Sleep(ss.dwWaitHint);

           if(not QueryServiceStatus( schs,ss))then
           begin
             // couldn't check status break from the loop
             break;
           end;

           if(ss.dwCheckPoint < dwChkP)then
           begin
             // QueryServiceStatus didn't increment dwCheckPoint as it should have.
             // avoid an infinite loop by breaking
             break;
           end;
         end;
       end;
     end;

     // close service handle
     CloseServiceHandle(schs);
   end;

   // close service control manager handle
   CloseServiceHandle(schm);
 end;

 // return TRUE if the service status is running
 Result :=SERVICE_RUNNING =ss.dwCurrentState;
end;

procedure TServiceTestForm.btnStopServiceClick(Sender: TObject);
begin
 Screen.Cursor :=crHourGlass;
 if ServiceStop('','EDBSRVR') then
   MessageDlg('Service stopped', mtInformation, [mbOk],0)
 else
   MessageDlg('Service not stopped (if running in Win 7 make sure you use Run as Administrator)', mtInformation, [mbOk],0);
 Screen.Cursor :=crDefault;
end;

function TServiceTestForm.ServiceStop(sMachine,sService :string ):boolean;
var
 schm,   // service control manager handle
 schs :SC_Handle;   // service handle
 ss :TServiceStatus;   // service status
 dwChkP :DWord;  // check point
begin
 // connect to the service control manager
 schm := OpenSCManager(PChar(sMachine),Nil,SC_MANAGER_CONNECT);

 // if successful...
 if(schm > 0)then
 begin
   // open a handle to the specified service
   // we want to stop the service and query service status
   schs := OpenService(schm,PChar(sService),SERVICE_STOP or SERVICE_QUERY_STATUS);

   // if successful...
   if(schs > 0)then
   begin
     if(ControlService(schs,SERVICE_CONTROL_STOP,ss))then
     begin
       // check status
       if(QueryServiceStatus(schs,ss))then
       begin
         while(SERVICE_STOPPED <> ss.dwCurrentState)do
         begin
           // dwCheckPoint contains a value that the service increments periodically to report its progress
           // during a lengthy operation.
           // save current value
           dwChkP := ss.dwCheckPoint;

           // wait a bit before checking status again dwWaitHint is the estimated amount of time the calling program
           // should wait before calling QueryServiceStatus() again
           // idle events should be
           // handled here...
           Sleep(ss.dwWaitHint);

           if(not QueryServiceStatus(schs,ss))then
           begin
             // couldn't check status break from the loop
             break;
           end;

           if(ss.dwCheckPoint <dwChkP)then
           begin
             // QueryServiceStatus didn't increment dwCheckPoint as it should have.
             // avoid an infinite loop by breaking
             break;
           end;
         end;
       end;
     end;

     // close service handle
     CloseServiceHandle(schs);
   end;

   // close service control manager handle
   CloseServiceHandle(schm);
 end;

 // return TRUE if the service status is stopped
 Result :=SERVICE_STOPPED =ss.dwCurrentState;
end;

procedure TServiceTestForm.btnQueryServiceClick(Sender: TObject);
begin
 Screen.Cursor :=crHourGlass;
 QueryService('','EDBSRVR');
 Screen.Cursor :=crDefault;
end;

procedure TServiceTestForm.QueryService(sMachine,sService :string);
var
 ServiceControlManagerHandle, ServiceHandle :SC_Handle;
 ServiceStatus :TServiceStatus;
 dwChkP :DWord;
begin
 ServiceControlManagerHandle :=OpenSCManager(PChar(sMachine),nil,SC_MANAGER_CONNECT);
 if(ServiceControlManagerHandle >0)then
 begin
   //we want to query the service status
   ServiceHandle :=OpenService(ServiceControlManagerHandle,PChar(sService),SERVICE_STOP or SERVICE_QUERY_STATUS);
   if(ServiceHandle >0)then
   begin
     if(QueryServiceStatus(ServiceHandle,ServiceStatus))then
     begin
       if ServiceStatus.dwCurrentState =SERVICE_RUNNING then
         MessageDlg('Service is running', mtInformation, [mbOk],0)
       else if ServiceStatus.dwCurrentState =SERVICE_STOPPED then
         MessageDlg('Service has been stopped or just installed', mtInformation, [mbOk],0)
       else
         MessageDlg('Service state is unknown', mtInformation, [mbOk],0);
     end;
     CloseServiceHandle(ServiceHandle);
   end;
   CloseServiceHandle(ServiceControlManagerHandle);
 end;
end;

end.
Image