2015-09-12 23 views
13

Se un programma .net non riesce a impostare esplicitamente il codice di uscita prima di terminare (chiamando Environment.Exit()/Appliation.Current.Shutdown()/...), qual è il codice di uscita per tale processo?Quali codici di uscita possono avere un programma .net quando Environment.Exit() non viene utilizzato?

Una terminazione normale risulta sempre in codice di uscita zero e quali sono gli altri casi possibili?

Secondo this answer alla relativa domanda Getting ExitCode From Exception Handler di Hans Passant: "se un programma muore un'eccezione quindi il codice di uscita è normalmente uguale al codice di errore eccezione sottostante".

Quindi un'eccezione uncaugth può fondere il codice di uscita. È questo il sempre il caso e il codice di errore di eccezione di sottostanti è sempre garantito per essere diverso da zero e in un intervallo specifico?

Ci sono altre circostanze in cui il framework .net o Windows possono impostare automaticamente un altro codice di uscita, come ad esempio un arresto anomalo non relativo alle eccezioni (è possibile?) O un arresto forzato?

Per dirla in altro modo, è possibile determinare in base al codice di uscita se il programma è terminato in modo anomalo o no?
Oppure, se in alcuni casi anormali si verifica un codice di uscita pari a zero, è possibile includere uno Environment.Exit(somevalue) in tutti i normali percorsi di terminazione per un programma e accertarsi che questo codice di uscita non possa mai verificarsi in caso di arresto anomalo?


Motivazione:
Dal not all exeptions are catchable senza soluzioni alternative gravi, e dal momento che ci possono essere altre cause di cessazione improvvisa programma diverso da excpetions non gestite fanno, facendo in modo che tutti i percorsi di codice di chiamata Environment.Exit() non è alwas possibile. Questo è il motivo per cui sono interessato a determinare se il codice di uscita può essere usato per determinare in modo affidabile se un programma è uscito normalmente.

+0

Ho aggiunto le differenze tra la mia domanda e il duplicato proposto. Mentre la seconda risposta aiuta anche con una parte della mia domanda, non risponde completamente, e la domanda stessa è completamente diversa. – HugoRune

+0

Suggerimento tangenziale: abilita Segnalazione errori di Windows, con l'opzione per creare minidump abilitati. In questo modo non hai solo un codice di uscita, ma anche i record delle eccezioni e gli stack parziali che puoi passare attraverso un debugger. (Come WinDBG che utilizza il debugger SOS.) Anche senza minidump WER riceve alcune informazioni sul messaggio di errore stesso. Per un'applicazione interna, è anche possibile configurare un server per l'invio automatico dei rapporti di arresto anomalo. Questa [pagina] (https://technet.microsoft.com/en-us/library/cc709644.aspx) su TechNet offre una buona panoramica. – theB

+0

Il codice di uscita è piuttosto inutile IMHO. Maggiori informazioni qui: http://stackoverflow.com/questions/4344923/processo-exit-code-when-process-is-killed-forcibly –

risposta

5

allora il suo codice di uscita è normalmente lo stesso del codice di errore di eccezione sottostante

Dopo 6 mesi, si dovrebbe aver accumulato una certa sicurezza che normalmente applica. Probabilmente ha funzionato bene, non è possibile ottenere una garanzia qui. Non si tratta solo di eccezioni non gestite che fanno terminare un processo e non si può mai essere sicuri che sia sempre lo stesso codice che viene eseguito quando un processo muore su un'eccezione.

C'è troppa roba là fuori che vuole essere coinvolto con questo e non è sempre della migliore qualità. In cima alla lista c'è sicuramente l'anti-malware, c'è un sacco di cr * pware là fuori e non saprai mai cosa stai incontrando. Il recente disastro Avast offre molte ragioni per essere preoccupato di questo. Non quasi dove finisce, le utility che sostituiscono il WER sono abbastanza comuni.

E tu sei completamente indifeso contro uno yokel che pensa che TerminateProcess() sia un buon modo per risolvere un problema di blocco dei file. O qualcuno che inciampa sul cavo di alimentazione e scolleghi la macchina.

Concentrarsi un po 'su perché si desidera conoscere il codice di uscita.Dovrebbe esserci qualcosa che fai dopo che usa il risultato del programma per continuare l'esecuzione. Convalidare il risultato.

2

È il processo che stai eseguendo da solo? Cioè, puoi controllare il suo codice di uscita in circostanze prevedibili? In tal caso, è possibile rilevare eventuali eccezioni generate e quindi restituire il proprio codice di eccezione non zero prevedibile (un valore specifico o il proprio intervallo). Vorrei utilizzare un numero negativo poiché i codici di errore di sistema sono positivi. In questo modo tu hai tre possibilità:

  1. Zero - il successo
  2. negativo - processo ha generato un'eccezione che sono stati in grado di catturare
  3. positivo - processo ha generato un'eccezione che non si poteva prendere. Sarebbe anormale.

Qualsiasi cosa diversa da quella sembra imprevedibile. Se qualcosa è così fuori dal normale che un processo non può nemmeno restituire un codice di uscita diverso da zero, anche il processo in attesa di quel codice di uscita potrebbe aver fallito. Il controllo di un codice di uscita diverso da zero è ciò che si può ragionevolmente fare per tenere conto della possibilità di un guasto a causa di una causa imprevista.

Non so se il numero 3 sia possibile, ma se stai cercando di rendere conto dell'ignoto, probabilmente è il massimo che puoi fare.

Ecco un esempio:

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; 
    } 
} 

è quello che si potrebbe fare. Ma non userei il codice di uscita per descrivere l'errore. Userei la registrazione per quello. Userei il codice di uscita per dire all'app chiamante cosa fare. Zero o non zero è probabilmente sufficiente per quello. Ho scritto codici di ritorno più complicati che indicano se l'errore era legato all'IO o all'SQL e alla fine non ne ho mai usato nessuno. Se fallisce, guardo il mio log per un messaggio di errore.