Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to restart Interbase

I try to follow http://edn.embarcadero.com/article/28604 for restarting Interbase. Here is some code:

program IBRestart;

{$APPTYPE CONSOLE}

uses
  SysUtils, winsvc;

var
  vManager, vService: SC_Handle;
  vtmp: TServiceStatus;
begin
  vManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if vManager > 0 then
  begin
    vService := OpenService(vManager, 'InterBaseGuardian', SERVICE_START or SERVICE_STOP);
    if vService = 0 then           // vService is always 0 here, why ?
      CloseServiceHandle(vManager)
    else
    if ControlService(vService, SERVICE_CONTROL_STOP, vTmp) and
       QueryServiceStatus(vService, vTmp) and
       (vTmp.dwCurrentState = SERVICE_STOPPED) then
    begin
      WriteLn('Success');
    end;
  end;
end.

I notice that the service is listed as "InterBase 2009 Guardian gds_db" in the services dialog. I have tried different variants of this as argument to OpenService without success... Any hints ?

EDIT: net start list the service as InterBase 2009 Guardian gds_db and InterBase 2009 Server gds_db

RaiseLastOSError return this in both cases: Project IBRestart.exe raised exception class EOSError with message 'System Error. Code: 1060. The specified service does not exist as an installed service'.

So vService is always 0 in the code above. I even try to stop another service like Themes and it actually works. Can it be the spaces in the string that must be special handled ? I tried to close IIS Admin and it returned the same error message as Interbase do.

like image 364
Roland Bengtsson Avatar asked Feb 27 '23 20:02

Roland Bengtsson


1 Answers

Maybe the service name is wrong or you do not have enough rights (need to start as administrator)? Hard to tell without any hints to what has gone wrong.

Please check if any of the calls signal an error (return code = 0) and check what the error is by calling RaiseLastOSError or SysErrorMessage(GetLastError) in that case. Also make sure to check for errors on the other calls. Please update your question with any new information that brings.

And change your check from > 0 to <> 0. 0 signals error, anything else success. A handle can be a negative number. And add some try..finally. And don't forget the code for starting the service again :) Also it might take a while before the service changes state after a call to ControlService so QueryServiceStatus might return SERVICE_STOP_PENDING for a while before actually stopping. Your code should account for it. See here for an example.

program IBRestart;

{$APPTYPE CONSOLE}

uses
  SysUtils, winsvc;

var
  vManager, vService: SC_Handle;
  vtmp: TServiceStatus;
begin
  vManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS);
  if vManager <> 0 then
  begin
    try
      vService := OpenService(vManager, 'InterBaseGuardian', SERVICE_START or SERVICE_STOP);
      if vService = 0 then      // vService is always 0 here, why ?
        RaiseLastOSError;       // This will give a hint why !
      else
        try
          Win32Check(ControlService(vService, SERVICE_CONTROL_STOP, vTmp));
          Win32Check(QueryServiceStatus(vService, vTmp));
          if vTmp.dwCurrentState = SERVICE_STOPPED then   // This might also be SERVICE_STOP_PENDING
            WriteLn('Success')
          else
            WriteLn('Failure');
        finally
          CloseServiceHandle(vService);
        end;
    finally
      CloseServiceHandle(vManager);
    end;
  end
  else
    RaiseLastOSError;
end.
like image 126
Lars Truijens Avatar answered Mar 06 '23 16:03

Lars Truijens