views:

266

answers:

3

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.

+4  A: 

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.
Lars Truijens
+1, all *very* valid points. BTW, running `net start` in a shell window gives a list of running services, with the correct names needed to identify them to the service manager.
mghie
Thanks for the code. But the main problem seems to be that OpenService did not recognize the servicestring I send.
Roland Bengtsson
I do not have Interbase installed, but you can find the service name in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services or use a tool like psservice (http://technet.microsoft.com/en-us/sysinternals/bb897542.aspx)
Lars Truijens
+2  A: 

Guardian is a service who restart the Ibserver.exe when it fall down : It was useful for old OS or when you run ibserver as an application. If you use Ibserver as a service, you can manage this directly in the service (Guardian is useless in this case).

Hugues Van Landeghem
Didn't know that. But I think it should be handled automatically by the Interbase installer.
Roland Bengtsson
+2  A: 

This is the batch file I use for restarting InterBase 2007, it shows you that on some machines the service names have an extra space in them:

rem jpl: 20071015 - on some machines, the guardian service has an extra space
net stop "InterBase 2007 Guardian gds_db"
net stop "InterBase 2007 Guardian gds_db "
net stop "InterBase 2007 Server gds_db"
net start "InterBase 2007 Guardian gds_db"
net start "InterBase 2007 Guardian gds_db "
pause

Note that I stop and start the Guardian twice; sometimes it does not react within the service stop/start time out period. I also stop the InterBase service specifically; it is hardly needed, but I had one time where the guardian service did stop, but the InterBase service did not stop.

--jeroen

Jeroen Pluimers
Excellent. That is enough for me!
Roland Bengtsson
glad it worked for you so well!
Jeroen Pluimers