4

我尝试按照http://edn.embarcadero.com/article/28604重新启动 Interbase。这是一些代码:

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.

我注意到该服务在服务对话框中被列为“InterBase 2009 Guardian gds_db”。我尝试了不同的变体作为 OpenService 的参数,但没有成功......有什么提示吗?

编辑: net start 将服务列为InterBase 2009 Guardian gds_dbInterBase 2009 Server gds_db

RaiseLastOSError 在这两种情况下都会返回:Project IBRestart.exe 引发异常类 EOSError,并带有消息“系统错误。代码:1060。指定的服务不作为已安装的服务存在。

所以 vService 在上面的代码中始终为 0。我什至尝试停止其他服务,例如 Themes,它确实有效。可以是字符串中的空格必须特殊处理吗?我试图关闭IIS Admin,它返回了与 Interbase 相同的错误消息。

4

3 回答 3

4

也许服务名称错误或者您没有足够的权限(需要以管理员身份启动)?很难在没有任何提示的情况下说出出了什么问题。

请检查是否有任何调用发出错误信号(返回代码 = 0),并在这种情况下通过调用 RaiseLastOSError 或 SysErrorMessage(GetLastError) 检查错误是什么。还要确保检查其他调用中的错误。请使用带来的任何新信息更新您的问题。

并将您的检查从 > 0 更改为 <> 0。0 表示错误,其他任何事情都成功。句柄可以是负数。并添加一些尝试..finally。并且不要忘记再次启动服务的代码 :) 此外,在调用 ControlService 之后服务更改状态可能需要一段时间,因此 QueryServiceStatus 可能会在实际停止之前返回 SERVICE_STOP_PENDING 一段时间。您的代码应该考虑到它。有关示例,请参见此处。

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.
于 2010-01-03T20:48:28.343 回答
2

Guardian是一项在 Ibserver.exe 崩溃时重新启动它的服务:它对旧操作系统或将 ibserver 作为应用程序运行时很有用。如果你使用 Ibserver 作为服务,你可以直接在服务中管理这个(Guardian 在这种情况下是没用的)。

于 2010-01-03T22:27:56.307 回答
2

这是我用于重新启动 InterBase 2007 的批处理文件,它向您展示了在某些机器上,服务名称中有一个额外的空间

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

请注意,我停止和启动 Guardian 两次;有时它在服务停止/启动超时期限内没有反应。我还专门停止了 InterBase 服务;几乎不需要,但我曾经有一次监护服务确实停止了,但 InterBase 服务并没有停止。

——杰伦

于 2010-01-04T10:14:04.173 回答