Come posso specificare il codice di uscita di un'applicazione console in .NET?


471

Ho un'applicazione console banale in .NET. È solo una parte di prova di un'applicazione più grande. Vorrei specificare il "codice di uscita" della mia applicazione console. Come faccio a fare questo?

Risposte:


599

3 opzioni:

  • Puoi restituirlo da Mainse dichiari Maindi restituire il tuo metodo int.
  • Puoi chiamare Environment.Exit(code).
  • È possibile impostare il codice di uscita utilizzando le proprietà: Environment.ExitCode = -1;. Questo verrà utilizzato se nient'altro imposta il codice di ritorno o utilizza una delle altre opzioni sopra).

A seconda dell'applicazione (console, servizio, app Web, ecc.) È possibile utilizzare diversi metodi.


12
Per quelli di voi che si chiedono perché questo non funzioni nel loro caso, assicuratevi che il vostro progetto sia compilato come "applicazione console" e non come "applicazione Windows".
Marcel Gosselin,

10
cosa succede se ho un'app WinForms che con alcuni argomenti voglio che si comporti come un'app console?
sebagomez,

5
Puoi anche digitare il programma maine come int (sostituisci void con int) e usare ad esempio "return -1;" per tornare dal programma principale. Questo è più portabile di Environment.Exit () (che dipende dall'ambiente).
Werner,

14
@DannyBeckett Per convenzione, un codice di uscita 0significa successo e un valore diverso da zero significa fallimento. return;indica il successo tramite il codice di uscita 0e return -1;indica il fallimento.
allonhadaya,

6
Puoi anche impostare il codice di uscita usando properties: Environment.ExitCode = -1;
t3b4n,

270

Oltre alle risposte che riguardano il ritorno int ... un appello alla sanità mentale. Per favore, definisci i tuoi codici di uscita in un enum, con le Bandiere se appropriato. Rende il debug e la manutenzione molto più semplici (e, come bonus, puoi facilmente stampare i codici di uscita nella schermata di aiuto - ne hai uno, giusto?).

enum ExitCode : int {
  Success = 0,
  InvalidLogin = 1,
  InvalidFilename = 2,
  UnknownError = 10
}

int Main(string[] args) {
   return (int)ExitCode.Success;
}

46
Potresti voler aggiungere che il valore di "0" per "Successo" non è casuale, ma in realtà il valore "standard" per quella situazione.
Christian.K,

39
QUESTO. Questo è il motivo per cui SO è il più grande sito Web nella storia di Internet. Questo consiglio non è prontamente disponibile in nessun libro di testo e può essere raccolto solo parlando con un professionista esperto. GRAZIE.
Daniel Szabo,

17
Dici che 0 è il valore standard per il successo, eppure quando converti 0/1 in booleano, 0 è falso e 1 è vero! Potrebbe essere più preciso affermare che un codice di uscita pari a 0 significa "nessun errore", anziché "esito positivo", poiché il codice di uscita è un ErrorResult e non semplicemente un risultato.
Mark Shapiro,

11
Per l'elenco completo della convenzione di Microsoft, consultare msdn.microsoft.com/en-us/library/windows/desktop/… . Qualcuno ha fatto un enorme elenco di cons e lo ha usato in un caso di cambio nei commenti più avanti.
nawfal,

5
@MarkShapiro, suppongo che 0 = Successprovenga dal fatto che è necessario un solo codice di successo, ma molti codici di errore, come 0, come non avere + o - in numeri interi di Computer, possono essere utilizzati per identificare in modo univoco il successo
Sebastian

50

Esistono tre metodi che è possibile utilizzare per restituire un codice di uscita da un'applicazione console.

  1. Modificare il Mainmetodo nell'applicazione in modo che restituisca un intinvece di void(una funzione che restituisce un Integerinvece di Subin VB.Net) e quindi restituire il codice di uscita da quel metodo.
  2. Impostare la proprietà Environment.ExitCode sul codice di uscita. Si noti che il metodo 1. ha la precedenza: se il Mainmetodo restituisce qualcosa di diverso da void(è a Subin VB.Net), il valore di questa proprietà verrà ignorato.
  3. Passare il codice di uscita al metodo Environment.Exit . Ciò interromperà immediatamente il processo rispetto agli altri due metodi.

Uno standard importante da osservare è che 0rappresenta il "successo".

Su un argomento correlato, considerare l'utilizzo di un'enumerazione per definire i codici di uscita che l'applicazione restituirà. Il FlagsAttribute vi permetterà di restituire una combinazione di codici.

Inoltre, assicurarsi che l'applicazione sia compilata come "Applicazione console".


1
Questo fa apparire un punto interessante. L'impostazione Environment.ExitCodenon chiude immediatamente il programma ma il Environment.Exitmetodo chiude immediatamente il programma
PsychoData,

1
Il codice di uscita funziona anche su applicazioni Windows. Se l'app sarebbe avviata da c #, attraverso un Processoggetto, è possibile chiedere l'oggetto a WaitForExit(), quindi richiedere il codice di uscita da esso.
Nyerguds,

43

Se stai per utilizzare il metodo suggerito da David, dovresti anche dare un'occhiata all'attributo [Flags].

Questo ti permette di fare operazioni un po 'sagge sugli enum.

[Flags]
enum ExitCodes : int
{
  Success = 0,
  SignToolNotInPath = 1,
  AssemblyDirectoryBad = 2,
  PFXFilePathBad = 4,
  PasswordMissing = 8,
  SignFailed = 16,
  UnknownError = 32
}

Poi

(ExitCodes.SignFailed | ExitCodes.UnknownError)

sarebbe 16 + 32. :)


3
Ciò implica che un programma direbbe "la tua password è sbagliata", quindi continua a provare a firmare qualunque cosa significhi, e si fermerà solo se fallisce. Dovresti tornare dopo aver fallito; qualsiasi altra cosa è un avvertimento e il programma dovrebbe comunque restituire 0.
Pete Kirkham,

3
Il fatto poco noto è che [Flags] non fa nulla per abilitare o disabilitare le operazioni bit a bit. Tutto ciò che fa è sovrascrivere il metodo ToString in modo che l'output rappresenti i flag bit a bit. Con o senza, è ancora possibile eseguire operazioni bit per bit.
Steven

3
@Steven è bello da sapere, ma consiglierei comunque di decorare enum destinati all '"utilizzo della bandiera" con quell'attributo, se non altro trasmette l'intenzione.
MarioDS,



11

Restituisci semplicemente il codice appropriato da main.

int main(string[] args)
{
      return 0; //or exit code of your choice
}

2
L'app console C # predefinita non dichiara affatto main. Dichiara static void Main(string[] args);
Mark Lakata l'

19
@Mark Lakta: Quindi cambiarlo, no?
Esteban Araya,

11

Usa ExitCode se il tuo main ha una firma di ritorno vuota, altrimenti devi "impostarla" in base al valore che restituisci.

Proprietà Environment.ExitCode

Se il metodo Main restituisce null, è possibile utilizzare questa proprietà per impostare il codice di uscita che verrà restituito all'ambiente chiamante. Se Main non restituisce nulla, questa proprietà viene ignorata. Il valore iniziale di questa proprietà è zero.


8

Come aggiornamento alla risposta di Scott Munro :

  • In C # 6.0 e VB.NET 14.0 (VS 2015), è richiesto Environment.ExitCode o Environment.Exit (exitCode) per restituire un codice diverso da zero da un'applicazione console. La modifica del tipo restituito di Mainnon ha alcun effetto.
  • In F # 4.0 (VS 2015), il valore di ritorno del mainpunto di ingresso è rispettato.

È possibile verificare il primo punto relativo a C # 6? Non riesco a trovare nulla online. Il valore restituito dalla funzione Main è allegato al codice di uscita del processo (almeno in tutti i compilatori precedenti), perché avrebbero dovuto modificarlo?
Arman McHitarian,

Prova aneddotica pura, ma mi sono appena imbattuto in questo nella mia libreria, dove semplicemente restituendo il mio codice di risultato / errore da Main()non impostato Process.ExitCodecome visto dall'applicazione chiamante.
Marcus Mangelsdorf,

Secondo MSDN int Mainè ancora possibile utilizzare un'alternativa a Environment.ExitCode. link
Arman McHitarian

Ho un'applicazione che esegue più thread. In determinate circostanze, devo bloccare alcuni thread tramite Thread.Abort (), prima di uscire dall'applicazione. In queste circostanze, int Main () {... thread.Abort (); ... return 0;} NON risulta in un codice di uscita del processo pari a 0: il codice di uscita del processo è -1. Sembra in alcune circostanze, MS ha deciso che la convenzione di utilizzare il valore restituito dal thread principale per impostare il codice di uscita del processo, non è abbastanza buona per loro. In tutta onestà, potrebbe essere un problema di temporizzazione: l'interruzione del thread potrebbe impostare il codice di uscita molto tardi nel gioco.
David I. McIntosh,

7

L'opzione di enumerazione è eccellente, ma può essere migliorata moltiplicando i numeri come in:

enum ExitCodes : int
{
  Success = 0,
  SignToolNotInPath = 1,
  AssemblyDirectoryBad = 2,
  PFXFilePathBad = 4,
  PasswordMissing = 8,
  SignFailed = 16,
  UnknownError = 32
}

Nel caso di più errori, sommando i numeri di errore specifici si otterrà un numero univoco che rappresenterà la combinazione di errori rilevati.

Ad esempio, un livello di errore di 6 può consistere solo in errori 4 e 2, 12 può consistere solo in errori 4 e 8, 14 può consistere solo in 2, 4 e 8 ecc.


2
Questo è se ti preoccupi di verificare ulteriori errori dopo aver riscontrato uno, però. La maggior parte delle app no.
Nyerguds,


0

Usa questo codice

Environment.Exit(0);

usa 0 come int se non vuoi restituire nulla.


Questo non risponde alla domanda di OP e restituire 0 sta restituendo qualcosa ...
PL
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.