2010-01-03 3 views
4

J'essaie de suivre http://edn.embarcadero.com/article/28604 pour redémarrer Interbase. Voici un code:Comment redémarrer 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. 

Je remarque que le service est répertorié comme "Interbase 2009 The Guardian gds_db" dans la boîte de dialogue des services. J'ai essayé différentes variantes de ceci comme argument à OpenService sans succès ... Des conseils?

EDIT: liste de départ net du service comme InterBase 2009 The Guardian gds_db et InterBase 2009 Server gds_db

RaiseLastOSError retourner ce dans les deux cas: Projet IBRestart.exe soulevé EOSError classe d'exception avec le message ' Erreur système. Code: 1060. Le service spécifié n'existe pas en tant que service installé ».

Ainsi, vService est toujours 0 dans le code ci-dessus. J'essaie même d'arrêter un autre service comme Themes et cela fonctionne réellement. Est-ce que ce peut être les espaces dans la chaîne qui doivent être spéciaux manipulés? J'ai essayé de fermer IIS Admin et il a renvoyé le même message d'erreur que Interbase.

Répondre

2

C'est le fichier batch que j'utilise pour redémarrer Interbase 2007, il vous montre que sur certaines machines les noms de service ont un espace supplémentaire dans les:

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 

Notez que j'arrêter et démarrer le Guardian deux fois; parfois, il ne réagit pas pendant la période d'arrêt/de démarrage du service. J'arrête également le service InterBase spécifiquement; il n'est guère nécessaire, mais j'ai eu une fois où le service de tutelle s'est arrêté, mais le service InterBase ne s'est pas arrêté.

--jeroen

+0

Excellent. C'est assez pour moi! –

+0

heureux qu'il a travaillé pour vous si bien! –

4

Peut-être le nom du service est faux ou vous n'avez pas assez de droits (besoin de démarrer en tant qu'administrateur)? Difficile à dire sans aucune allusion à ce qui a mal tourné.

Veuillez vérifier si l'un des appels signale une erreur (code de retour = 0) et vérifiez l'erreur en appelant RaiseLastOSError ou SysErrorMessage (GetLastError) dans ce cas. Assurez-vous également de vérifier les erreurs sur les autres appels. S'il vous plaît mettre à jour votre question avec toute nouvelle information qui apporte.

Et changer votre chèque de> 0 à <> 0. 0 erreur de signaux, rien d'autre succès. Un handle peut être un nombre négatif. Et ajoutez un peu try..finally. Et n'oubliez pas le code pour redémarrer le service :) En outre, il peut s'écouler un certain temps avant que le service ne change d'état après un appel à ControlService afin que QueryServiceStatus renvoie SERVICE_STOP_PENDING pendant un moment avant de s'arrêter. Votre code devrait en tenir compte. Voir here pour un exemple.

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. 
+0

+1, tous les points * très * valides. BTW, en cours d'exécution 'net start' dans une fenêtre shell donne une liste de services en cours, avec les noms corrects nécessaires pour les identifier au gestionnaire de services. – mghie

+0

Merci pour le code.Mais le principal problème semble être qu'OpenService n'a pas reconnu la chaîne de services que j'ai envoyée. –

+0

Je n'ai pas installé Interbase, mais vous pouvez trouver le nom du service dans HKEY_LOCAL_MACHINE \ SYSTEM \ CurrentControlSet \ Services ou utiliser un outil comme psservice (http://technet.microsoft.com/en-us/sysinternals/bb897542.aspx) –

2

Guardian est un service qui redémarre le Ibserver.exe quand il tombe vers le bas: Il était utile pour l'ancien système d'exploitation ou lorsque vous exécutez ibserver comme une application. Si vous utilisez Ibserver en tant que service, vous pouvez le gérer directement dans le service (Guardian est inutile dans ce cas).

+0

Je ne le savais pas. Mais je pense qu'il devrait être géré automatiquement par l'installateur Interbase. –