2015-09-12 4 views
13

Wenn ein .net-Programm, bevor die Einstellung des Exit-Code explizit gesetzt fehlschlägt (von Environment.Exit()/Appliation.Current.Shutdown()/... Aufruf), was die für diesen Prozess Exit-Code ist?Welche Exit-Codes kann ein .net-Programm haben, wenn Environment.Exit() nicht verwendet wird?

Gibt es eine normale Beendigung führen immer in Exit-Code Null, und was sind die anderen möglichen Fälle?

Nach this answer auf die damit verbundene Frage Getting ExitCode From Exception Handler von Hans Passant: „, wenn ein Programm auf einer Ausnahme stirbt dann ist der Exit-Code normalerweise gleich den Code zugrunde liegenden Ausnahmefehlers“.

So eine uncaugth Ausnahme kann den Exit-Code cange. Ist dies immer der Fall, und ist die zugrunde liegende Ausnahme Fehlercode immer garantiert von Null, und in einem bestimmten Bereich zu sein?

Gibt es andere Umstände, unter denen das .NET-Framework oder Windows automatisch einen anderen Exit-Code festlegen kann, z. B. einen nicht-exemplarischen Absturz (ist das möglich?) Oder einen erzwungenen Task kill?

Um es anders auszudrücken, könnte ich durch den Exit-Code feststellen, ob das Programm in irgendeiner abnormalen Weise beendet wurde oder nicht?
Oder wenn ein Exit-Code von Null in einigen abnormalen Fällen auch auftreten kann, könnte ich eine Environment.Exit(somevalue) in alle normalen Beendigungspfade für ein Programm einschließen, und sicher sein, dass dieser Exit-Code im Falle eines Absturzes nie auftreten kann?


Motivation:
Seit not all exeptions are catchable ohne schwere Abhilfen, und da gibt es andere Ursachen für andere plötzliche Beendigung des Programms sein kann als abgefangene excpetions, um sicherzustellen, dass alle Codepfade rufen Environment.Exit() ist nicht alwas möglich. Deshalb bin ich daran interessiert festzustellen, ob der Exit-Code verwendet werden kann, um zuverlässig zu erkennen, ob ein Programm normal beendet wurde.

+0

Ich fügte die Unterschiede zwischen meiner Frage und dem vorgeschlagenen Duplikat hinzu. Während die zweite Antwort auch bei einem Teil meiner Frage hilft, beantwortet sie sie nicht vollständig, und die Frage selbst ist völlig anders. – HugoRune

+0

Tangentialer Vorschlag: Aktivieren Sie die Windows-Fehlerberichterstattung mit der Option zum Erstellen von Minidumps. Auf diese Weise haben Sie nicht nur einen Exit-Code, sondern auch die Exception-Records und Partial-Stacks, die Sie durch einen Debugger führen können. (Wie WinDBG mit dem SOS-Debugger.) Auch ohne Minidumps WER fängt einige Informationen über die Fehlermeldung selbst. Für eine interne Anwendung können Sie sogar einen Server für die automatische Übermittlung der Absturzberichte einrichten. Diese [Seite] (https://technet.microsoft.com/en-us/library/cc709644.aspx) auf TechNet hat einen guten Überblick. – theB

+0

Der Exit-Code ist ziemlich nutzlos IMHO. Mehr hier: http://stackoverflow.com/questions/4344923/process-exit-code-when-process-is-killed-forcibly –

Antwort

5

dann sein Exit-Code ist normalerweise das gleiche wie der zugrunde liegenden Ausnahmefehlercode

Nach 6 Monaten, sollten Sie etwas Vertrauen aufgebaut haben, dass normalerweise gelten. Wahrscheinlich hat es gut geklappt, man kann hier keine Garantie bekommen. Es ist nicht nur unbehandelte Ausnahmen, dass ein Prozess machen beenden und man kann nie sicher sein, dass es immer der gleiche Code, der ausgeführt wird, wenn ein Prozess auf einer Ausnahme stirbt.

Es gibt viel zu viele Sachen da draußen, die sich damit beschäftigen wollen und es ist nicht immer von bester Qualität. Oben auf der Liste ist sicherlich Anti-Malware-, gibt es eine Menge von Cr * pware da draußen, und Sie werden nie wissen, was Sie laufen in. Die jüngste Katastrophe von Avast gibt viele Gründe, sich darüber Gedanken zu machen. Nicht annähernd, wo es endet, Utilities, die WER ersetzen, sind häufig genug.

Und Sie sind völlig wehrlos gegen einen Yokel, der denkt, dass TerminateProcess() eine gute Möglichkeit ist, ein File-Locking-Problem zu lösen. Oder jemand, der über das Netzkabel stolpert und den Stecker aus der Steckdose zieht.

ein wenig Fokus auf warum Sie den Exit-Code wissen wollen.Es sollte etwas geben, was Sie als nächstes tun, das das Ergebnis des Programms verwendet, um fortzufahren. Validiere das Ergebnis.

2

Ist der Prozess, den Sie ausführen, Ihr eigenes? Das heißt, können Sie den Ausgangscode unter vorhersehbaren Umständen kontrollieren? Wenn dies der Fall ist, können Sie jede ausgelöste Ausnahme abfangen und dann Ihren eigenen vorhersehbaren Ausnahmecode (einen bestimmten Wert oder Ihren eigenen Bereich) zurückgeben. Ich würde eine negative Zahl verwenden, da Systemfehlercodes positiv sind. So können Sie drei Möglichkeiten haben:

  1. Null - Erfolg
  2. Negative - Prozess hat eine Ausnahme, die Sie in der Lage waren
  3. Positive zu fangen - Prozess hat eine Ausnahme, die Sie nicht fangen konnte. Das wäre abnormal.

Alles andere als das scheint unvorhersehbar. Wenn etwas so weit außerhalb der Norm liegt, dass ein Prozess nicht einmal einen Nicht-Null-Beendigungscode zurückgeben kann, dann kann der Prozess, der auf diesen Beendigungscode wartet, ebenfalls fehlgeschlagen sein. Die Prüfung auf einen Beendigungscode ungleich null ist das, was Sie vernünftigerweise tun können, um die Möglichkeit eines Ausfalls aufgrund einer unvorhergesehenen Ursache zu berücksichtigen.

Ich weiß nicht, ob # 3 sogar möglich ist, aber wenn Sie versuchen, das Unbekannte zu erklären, dann ist es wahrscheinlich das Meiste, was Sie tun können.

Hier ist ein Beispiel:

internal class Program 
{ 
    private static void Main(string[] args) 
    { 
     var exitCode = 0; 
     try 
     { 
      //do something 
     } 
     catch (SystemException systemEx) 
     { 
      //log 
      exitCode = -systemEx.HResult; 
     } 
     catch (Exception ex) 
     { 
      //log 
      Environment.ExitCode = int.MinValue; 

     } 
     Environment.ExitCode = exitCode; 
    } 
} 

Das ist, was Sie könnte tun. Aber ich würde den Exit-Code nicht verwenden, um den Fehler zu beschreiben. Ich würde das Protokollieren dafür verwenden. Ich würde den Exit-Code verwenden, um der anrufenden App mitzuteilen, was zu tun ist. Null oder Nicht-Null ist dafür wahrscheinlich ausreichend. Ich habe kompliziertere Rückkehrcodes geschrieben, die anzeigen, ob der Fehler IO-bezogen oder SQL-bezogen war und am Ende habe ich nie etwas davon verwendet. Wenn es fehlschlägt, schaue ich in meinem Protokoll nach einer Fehlermeldung.

Verwandte Themen