Question

Mise à jour : Il semble être spécifique à D2007. Il travaille dans D2010 comme il a travaillé dans l'ancienne version.

Je voudrais revenir un code de sortie en fonction du type d'exception pris dans le bloc gestionnaire ÉCEPTION comme:

program test;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  Exitcode: Integer;
begin
  Writeln('Enter error code:');
  Readln(Exitcode);
  try
    raise EExternal.Create('sdsdkfjh');
  except
    on E:EExternal do
    begin
      Writeln(E.Classname, ': ', E.Message);
      Halt(Exitcode);
    end;
  end;
end.

Malheureusement, dans D2007, appelant Halt (n) à partir d'un bloc d'exception renvoie toujours un code de sortie 1 , peu importe ce que vous passez à Halt ().

Il semble que la sortie d'un appel gestionnaire d'exception Finaliser, qui efface les en attente (non Abort) Exceptions, appelant SysUtils.ExceptHandler:

procedure ExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer); far;
begin
  ShowException(ExceptObject, ExceptAddr);
  Halt(1); // <= @#$##@#$!
end;

Et peu importe ce que le code de sortie que je voulais que je reçois Halt(1)!

La question est: Comment puis-je retourner simplement le code de sortie désiré en fonction de quelle exception a été soulevée?

Était-ce utile?

La solution

Est-ce que ce travail?

NeedHalt := False;
try
  raise EExternal.Create('sdsdkfjh');
except
  on E:EExternal do
  begin
    Writeln(E.Classname, ': ', E.Message);
    NeedHalt := True;
  end;
end;
if NeedHalt then
  Halt(Exitcode); 

Ou cela?

try
  raise EExternal.Create('sdsdkfjh');
except
  on E:EExternal do
  begin
    Writeln(E.Classname, ': ', E.Message);
    AcquireExceptionObject;
    Halt(Exitcode); 
  end;
end;

Quoi qu'il en soit: c'est un bogue dans D2007, qui a été fixé dans D2010 .

Autres conseils

En fait ... il semble fonctionner comme prévu ....

je votre code ...

program test1;

{$APPTYPE CONSOLE}

uses
  SysUtils;

var
  Exitcode: Integer;
begin
  Writeln('Enter error code:');
  Readln(Exitcode);
  try
    raise EExternal.Create('sdsdkfjh');
  except
    on E:EExternal do
    begin
      Writeln(E.Classname, ': ', E.Message);
      Halt(Exitcode);
    end;
  end;
end.

Compilé dans Delphi 5, il a couru dans une boîte DOS sous XP ...

C:\>test1
Enter error code:
111
EExternal: sdsdkfjh

C:\>echo %errorlevel%
111

C:\>

Notez que les niveaux d'erreur DOS sont limités à la plage de 0 à 65535. Faisant écho% ERRORLEVEL% est le moyen le plus rapide pour voir le niveau d'erreur.

Ne pas oublier que la lecture du errorlevel efface.

Si vous voulez abandonner immédiatement le programme sans nettoyage, et retourner un code de sortie, essayez ExitProcess . Voir l'article pour quelques mises en garde sur l'utilisation ExitProcess, cependant.

Utilisation de l'arrêt (I) génère des fuites de mémoire (vous pouvez voir que si vous avez activé les MemoryLeaks FastMM avec ReportMemoryLeaksOnShutdown: = true;)

Il est préférable d'utiliser un « Clean » EXIT et ExitCode avant la sortie.

Dans une section principale d'une application de la console par exemple:

ExitCode:=I;
exit;

Si la fonction intégrée gestion des exceptions ne fait pas ce que vous voulez, puis le remplacer par votre propre:

function ExitCodeExceptHandler(ExceptObject: TObject; ExceptAddr: Pointer);
begin
  ShowException(ExceptObject, ExceptAddr);
  if ExitCode = 0 then
    ExitCode := 1;
  Halt(ExitCode);
end;

assignons à l'économie mondiale System.ExceptProc variable lorsque le début du programme:

ExceptProc := @ExitCodeExceptHandler;

Je l'ai mis en œuvre pour utiliser la variable globale ExitCode . Si elle est toujours à sa valeur par défaut de 0, la fonction revient au comportement Delphi d'origine de sortir avec 1, mais si le code de sortie a déjà été fixée à autre chose, cela va mettre un terme à cette valeur à la place. La première chose Halt n'est définie la variable globale ExitCode, de sorte que votre code ne devrait pas avoir besoin d'autres changements (bien que je choisirais un autre nom pour la variable Exitcode). Votre appel à Halt fixera la variable globale ExitCode et procéder ensuite à arrêter le programme. Le gestionnaire d'exception remarquerez que ExitCode est déjà défini et Halt re appel à cette valeur au lieu de 1.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top