Comment spécifier le code de sortie d'une application console dans .NET?

471

J'ai une application console triviale dans .NET. C'est juste une partie test d'une application plus large. Je voudrais spécifier le "code de sortie" de mon application console. Comment puis-je faire cela?

MrDatabase
la source

Réponses:

599

3 options:

  • Vous pouvez le renvoyer Mainsi vous déclarez votre Mainméthode à renvoyer int.
  • Vous pouvez appeler Environment.Exit(code).
  • Vous pouvez définir le code de sortie en utilisant les propriétés: Environment.ExitCode = -1;. Cela sera utilisé si rien d'autre ne définit le code retour ou n'utilise l'une des autres options ci-dessus).

Selon votre application (console, service, application web, etc.), différentes méthodes peuvent être utilisées.

TheSoftwareJedi
la source
12
Pour ceux d'entre vous qui se demandent pourquoi cela ne fonctionne pas dans leur cas, assurez-vous que votre projet est compilé comme une "application console" et non comme une "application Windows".
Marcel Gosselin
10
que faire si j'ai une application WinForms qui, avec certains arguments, je veux qu'elle se comporte comme une application console?
sebagomez
5
Vous pouvez aussi simplement taper le programme maine comme int (remplacer void par int) et utiliser par exemple "return -1;" pour revenir du programme principal. C'est plus portable que Environment.Exit () (qui dépend de l'environnement).
werner
14
@DannyBeckett Par convention, un code de sortie 0signifie succès et non nul signifie échec. return;indique la réussite via le code de sortie 0et return -1;indique l'échec.
allonhadaya
6
Vous pouvez également définir le code de sortie à l'aide des propriétés: Environment.ExitCode = -1;
t3b4n
270

En plus des réponses couvrant les retours int ... un plaidoyer pour la raison. Veuillez définir vos codes de sortie dans une énumération, avec des drapeaux, le cas échéant. Cela facilite le débogage et la maintenance (et, en prime, vous pouvez facilement imprimer les codes de sortie sur votre écran d'aide - vous en avez un, non?).

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

int Main(string[] args) {
   return (int)ExitCode.Success;
}
Mark Brackett
la source
46
Vous voudrez peut-être ajouter que la valeur de "0" pour "Succès" n'est pas par hasard, mais en fait la valeur "standard" pour cette situation.
Christian.K
39
CETTE. C'est pourquoi SO est le plus grand site Web de l'histoire d'Internet. Ces conseils ne sont disponibles dans aucun manuel et ne peuvent être glanés qu'en discutant avec un professionnel chevronné. MERCI.
Daniel Szabo
17
Vous dites que 0 est la valeur standard du succès, et pourtant lors de la conversion de 0/1 en booléen, 0 est faux et 1 est vrai! Il peut être plus précis de dire qu'un code de sortie de 0 signifie «pas d'erreur», plutôt que «succès», car le code de sortie est un ErrorResult et pas simplement un résultat.
Mark Shapiro
11
Pour la liste complète des conventions Microsoft, voir msdn.microsoft.com/en-us/library/windows/desktop/… . Un gars a fait une énorme liste de consts et l'a utilisé dans un boîtier de commutateur dans les commentaires ci-dessous.
nawfal
5
@MarkShapiro, je suppose que cela 0 = Successvient du fait qu'il n'y a qu'un seul code de réussite nécessaire, mais de nombreux codes d'erreur, tels que 0, comme n'ayant pas de + ou - dans les entiers informatiques, peuvent être utilisés pour identifier de manière unique le succès
Sebastian
50

Il existe trois méthodes que vous pouvez utiliser pour renvoyer un code de sortie à partir d'une application console.

  1. Modifiez la Mainméthode dans votre application afin qu'elle renvoie un intau lieu de void(une fonction qui renvoie un Integerau lieu de Subdans VB.Net), puis renvoyez le code de sortie de cette méthode.
  2. Définissez la propriété Environment.ExitCode sur le code de sortie. Notez que la méthode 1. a la priorité - si la Mainméthode renvoie autre chose que void(est un Subdans VB.Net) alors la valeur de cette propriété sera ignorée.
  3. Passez le code de sortie à la méthode Environment.Exit . Cela mettra immédiatement fin au processus, contrairement aux deux autres méthodes.

Une norme importante à observer est celle qui 0représente le «succès».

Sur un sujet connexe, envisagez d'utiliser une énumération pour définir les codes de sortie que votre application va renvoyer. Le FlagsAttribute vous permettra de renvoyer une combinaison de codes.

Assurez-vous également que votre application est compilée en tant qu '«application console».

Scott Munro
la source
1
Cela soulève un point intéressant. Le paramètre Environment.ExitCodene ferme pas le programme immédiatement mais la Environment.Exitméthode ferme le programme immédiatement
PsychoData
1
Le code de sortie fonctionne également sur les applications Windows. Si l'application doit être démarrée à partir de c #, via un Processobjet, vous pouvez demander à l'objet de WaitForExit(), puis lui demander le code de sortie.
Nyerguds
43

Si vous allez utiliser la méthode suggérée par David, vous devriez également jeter un œil à l'attribut [Flags].

Cela vous permet d'effectuer des opérations peu judicieuses sur les énumérations.

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

alors

(ExitCodes.SignFailed | ExitCodes.UnknownError)

serait 16 + 32. :)

Aron Tsang
la source
3
Cela implique qu'un programme dirait «votre mot de passe est incorrect», puis essaiera de signer tout ce qu'il signe et ne s'arrêtera qu'en cas d'échec. Vous devez revenir une fois que vous avez échoué; toute autre chose est un avertissement et le programme devrait toujours retourner 0.
Pete Kirkham
3
Le fait peu connu est que [Flags] ne fait rien pour activer ou désactiver les opérations au niveau du bit. Il ne fait que remplacer la méthode ToString afin que la sortie représente les drapeaux au niveau du bit. Avec ou sans, vous pouvez toujours effectuer des opérations au niveau du bit.
Steven
3
@Steven, c'est bon à savoir, mais je recommanderais quand même de décorer des énumérations destinées à "l'utilisation d'indicateurs" avec cet attribut, si rien d'autre ne traduit l'intention.
MarioDS
25
int code = 2;
Environment.Exit( code );
cheval pâle
la source
17
Toute raison technique pour laquelle vous n'avez pas simplement écrit "Environment.Exit (2);" ?
Blorgbeard est sorti le
53
Attribuer un nombre magique à une variable avec un nom sans signification ne le rend pas moins magique.
Blorgbeard est sorti
11

Renvoyez simplement le code approprié de main.

int main(string[] args)
{
      return 0; //or exit code of your choice
}
Esteban Araya
la source
2
L'application console C # par défaut ne déclare pas du tout main. Il déclare static void Main(string[] args);
Mark Lakata
19
@Mark Lakta: Alors changez-le, non?
Esteban Araya
11

Utilisez ExitCode si votre main a une signature de retour nulle, sinon vous devez la "définir" en fonction de la valeur que vous retournez.

Environment.ExitCode, propriété

Si la méthode Main renvoie void, vous pouvez utiliser cette propriété pour définir le code de sortie qui sera renvoyé à l'environnement appelant. Si Main ne retourne pas void, cette propriété est ignorée. La valeur initiale de cette propriété est zéro.

crashmstr
la source
8

En guise de mise à jour de la réponse de Scott Munro :

  • Dans C # 6.0 et VB.NET 14.0 (VS 2015), Environment.ExitCode ou Environment.Exit (exitCode) est requis pour renvoyer un code différent de zéro à partir d'une application console. La modification du type de retour de Mainn'a aucun effet.
  • Dans F # 4.0 (VS 2015), la valeur de retour du mainpoint d'entrée est respectée.
Vern DeHaven
la source
Votre 1er point concernant C # 6 peut-il être vérifié? Je n'arrive pas à trouver quoi que ce soit en ligne. La valeur de retour de la fonction Main est attachée au code de sortie du processus (au moins dans tous les compilateurs précédents), pourquoi auraient-ils dû changer cela?
Arman McHitarian
Des preuves anecdotiques pures, mais je suis juste tombé sur cela dans ma propre bibliothèque, où le simple retour de mon code de résultat / d'erreur Main()n'a pas défini le Process.ExitCodecomme vu par l'application appelante.
Marcus Mangelsdorf
MSDN prétend int Mainqu'il peut toujours être utilisé comme alternative à Environment.ExitCode. lien
Arman McHitarian
J'ai une application qui exécute plusieurs threads. Dans certaines circonstances, je dois écraser certains threads via Thread.Abort (), avant de quitter l'application. Dans ces circonstances, int Main () {... thread.Abort (); ... return 0;} n'entraîne PAS un code de sortie de processus de 0: le code de sortie de processus est -1. Il semble que dans certaines circonstances, MS a décidé que la convention d'utiliser la valeur de retour du thread principal pour définir le code de sortie du processus n'est pas suffisante pour eux. En toute honnêteté, cela pourrait être un problème de timing: l'abandon du thread pourrait définir le code de sortie très tard dans le jeu.
David I. McIntosh
7

L'option d'énumération est excellente mais peut être améliorée en multipliant les nombres comme dans:

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

Dans le cas d'erreurs multiples, l'ajout des numéros d'erreur spécifiques ensemble vous donnera un numéro unique qui représentera la combinaison des erreurs détectées.

Par exemple, un niveau d'erreur de 6 ne peut se composer que des erreurs 4 et 2, 12 ne peut se composer que des erreurs 4 et 8, 14 ne peut se composer que de 2, 4 et 8, etc.

David
la source
2
C'est si vous prenez la peine de vérifier d'autres erreurs après en avoir rencontré un. La plupart des applications ne le font pas.
Nyerguds
3

Mes 2 cents:

Vous pouvez trouver les codes d'erreur système ici: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

Vous trouverez les codes typiques comme 2 pour «fichier non trouvé» ou 5 pour «accès refusé».

Et lorsque vous tombez sur un code inconnu, vous pouvez utiliser cette commande pour découvrir ce que cela signifie:

net helpmsg decimal_code

par exemple

net helpmsg 1

Retour

Fonction incorrecte

Fred Mauroy
la source
0

Utilisez ce code

Environment.Exit(0);

utilisez 0 comme int si vous ne voulez rien retourner.

Swastik Bhattacharyya
la source
Cela ne répond pas à la question d'OP et retourner 0, c'est retourner quelque chose ...
PL