Jak określić kod wyjścia aplikacji konsoli w .NET?

471

Mam prostą aplikację konsolową w .NET. To tylko część testowa większej aplikacji. Chciałbym określić „kod wyjścia” mojej aplikacji konsoli. Jak mam to zrobic?

MrDatabase
źródło

Odpowiedzi:

599

3 opcje:

  • Możesz go zwrócić, Mainjeśli zadeklarujesz Mainmetodę zwrotu int.
  • Można zadzwonić Environment.Exit(code).
  • Można ustawić kod wyjścia przy użyciu właściwości: Environment.ExitCode = -1;. Będzie to wykorzystane, jeśli nic więcej nie ustawi kodu powrotu lub nie użyje jednej z pozostałych opcji powyżej).

W zależności od aplikacji (konsola, usługa, aplikacja internetowa itp.) Można stosować różne metody.

TheSoftwareJedi
źródło
12
Dla tych, którzy zastanawiają się, dlaczego w ich przypadku to nie działa, upewnij się, że Twój projekt jest skompilowany jako „aplikacja konsolowa”, a nie jako „aplikacja Windows”.
Marcel Gosselin,
9
co jeśli mam aplikację WinForms, która z niektórymi argumentami chce, aby działała jak aplikacja konsolowa?
sebagomez,
5
Możesz także wpisać program maine jako int (zastąp void przez int) i użyć np. „Return -1;” wrócić z programu głównego. Jest to bardziej przenośne niż Environment.Exit () (które zależy od środowiska).
werner
14
@DannyBeckett Zgodnie z konwencją kod wyjścia 0oznacza sukces, a niezerowy oznacza niepowodzenie. return;wskazuje sukces poprzez kod wyjścia 0i return -1;wskazuje niepowodzenie.
allonhadaya
6
Możesz także ustawić kod wyjścia za pomocą właściwości: Environment.ExitCode = -1;
t3b4n
270

Oprócz odpowiedzi dotyczących powrotu int ... prośba o rozsądek. Proszę, proszę zdefiniować kody wyjścia w wyliczeniu, w razie potrzeby z flagami. To sprawia, że ​​debugowanie i konserwacja są o wiele łatwiejsze (a jako bonus możesz łatwo wydrukować kody wyjścia na ekranie pomocy - masz jeden z nich, prawda?).

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

int Main(string[] args) {
   return (int)ExitCode.Success;
}
Mark Brackett
źródło
46
Możesz dodać, że wartość „0” dla „Sukcesu” nie jest przypadkowa, ale w rzeczywistości „standardowa” wartość dla tej sytuacji.
Christian.K
39
TO. Właśnie dlatego SO jest największą witryną w historii Internetu. Ta rada nie jest łatwo dostępna w żadnym podręczniku i można ją uzyskać jedynie rozmawiając z doświadczonym profesjonalistą. DZIĘKUJĘ CI.
Daniel Szabo
17
Mówisz, że 0 jest standardową wartością sukcesu, a jednak podczas konwersji 0/1 na wartość logiczną, 0 jest fałszem, a 1 jest prawdą! Bardziej dokładne może być stwierdzenie, że kod wyjścia 0 oznacza „brak błędu”, a nie „sukces”, ponieważ kod wyjścia to ErrorResult, a nie tylko wynik.
Mark Shapiro,
11
Aby uzyskać pełną listę konwencji Microsoft, zobacz msdn.microsoft.com/en-us/library/windows/desktop/… . Jakiś facet stworzył ogromną listę stałych i użył jej w przypadku przełącznika w komentarzach poniżej.
nawfal
5
@MarkShapiro, chyba 0 = Successwynika z faktu, że potrzebny jest tylko jeden kod sukcesu, ale wielu kodów błędów, takich jak 0, ponieważ nie ma + lub - w liczbach całkowitych komputera, można użyć do jednoznacznej identyfikacji sukcesu
Sebastian
49

Istnieją trzy metody zwracania kodu wyjścia z aplikacji konsoli.

  1. Zmodyfikuj Mainmetodę w swojej aplikacji, aby zwracała wartość intzamiast void(funkcja, która zwraca wartość Integerzamiast zamiast Subw VB.Net), a następnie zwraca kod wyjścia z tej metody.
  2. Ustaw właściwość Environment.ExitCode na kod wyjścia. Zauważ, że metoda 1. ma pierwszeństwo - jeśli Mainmetoda zwróci coś innego niż void(jest Subw VB.Net), wówczas wartość tej właściwości zostanie zignorowana.
  3. Przekaż kod zakończenia do metody Environment.Exit . Spowoduje to natychmiastowe zakończenie procesu, w przeciwieństwie do pozostałych dwóch metod.

Ważnym standardem, którego należy przestrzegać, jest 0„sukces”.

W pokrewnym temacie rozważ użycie wyliczenia do zdefiniowania kodów zakończenia, które aplikacja zwróci. FlagsAttribute pozwoli Ci powrócić kombinacji kodów.

Upewnij się także, że twoja aplikacja jest skompilowana jako „Aplikacja konsolowa”.

Scott Munro
źródło
1
To porusza interesujący punkt. Ustawienie Environment.ExitCodenie zamyka programu natychmiast, ale Environment.Exitmetoda natychmiast zamyka program
PsychoData
1
Kod zakończenia działa również w aplikacjach systemu Windows. Jeśli aplikacja zostanie uruchomiona od c #, poprzez Processobiekt, możesz poprosić o obiekt WaitForExit(), a następnie poprosić o kod wyjścia z niego.
Nyerguds
43

Jeśli zamierzasz skorzystać z metody sugerowanej przez Davida, powinieneś także spojrzeć na atrybut [Flagi].

To pozwala ci wykonywać nieco mądre operacje na wyliczeniach.

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

Następnie

(ExitCodes.SignFailed | ExitCodes.UnknownError)

będzie 16 + 32. :)

Aron Tsang
źródło
3
Oznacza to, że program powie „hasło jest nieprawidłowe”, a następnie spróbuje podpisać cokolwiek, co podpisuje, i zatrzyma się tylko wtedy, gdy się nie powiedzie. Powinieneś powrócić, gdy ci się nie uda; wszystko inne jest ostrzeżeniem, a program powinien nadal zwrócić 0.
Pete Kirkham,
3
Mało znanym faktem jest to, że [Flagi] nic nie robią, aby włączyć lub wyłączyć operacje bitowe. Wszystko, co robi, to przesłonięcie metody ToString, aby dane wyjściowe reprezentowały flagi bitowe. Z nim lub bez niego nadal możesz wykonywać operacje bitowe.
Steven
3
@ Steven to miło wiedzieć, ale nadal polecam dekorowanie wyliczeń przeznaczonych do „użycia flagi” za pomocą tego atrybutu, jeśli nic więcej nie przekazuje zamiaru.
MarioDS
25
int code = 2;
Environment.Exit( code );
Blady koń
źródło
17
Z jakiegokolwiek powodu technicznego nie napisałeś po prostu „Environment.Exit (2);” ?
Blorgbeard wyszedł
52
Przypisanie magicznej liczby do zmiennej o bezsensownej nazwie nie czyni jej mniej magiczną.
Blorgbeard jest niedostępny
11

Wystarczy zwrócić odpowiedni kod z głównego.

int main(string[] args)
{
      return 0; //or exit code of your choice
}
Esteban Araya
źródło
2
Domyślna aplikacja konsoli C # w ogóle nie deklaruje głównego. Deklaruje static void Main(string[] args);
Mark Lakata,
19
@Mark Lakta: Więc zmień to, nie?
Esteban Araya
11

Użyj ExitCode, jeśli twój main ma podpis void return, w przeciwnym razie musisz go „ustawić” na podstawie zwracanej wartości.

Environment.ExitCode Właściwość

Jeśli metoda Main zwróci wartość void, możesz użyć tej właściwości do ustawienia kodu wyjścia, który zostanie zwrócony do środowiska wywołującego. Jeśli Main nie zwróci void, ta właściwość jest ignorowana. Początkowa wartość tej właściwości wynosi zero.

crashmstr
źródło
8

Jako aktualizacja Scott Munro jest odpowiedź :

  • W językach C # 6.0 i VB.NET 14.0 (VS 2015) wymagane jest albo Environment.ExitCode lub Environment.Exit (exitCode), aby zwrócić niezerowy kod z aplikacji konsoli. Zmiana typu zwrotu Mainnie ma wpływu.
  • W F # 4.0 (VS 2015) przestrzegana jest wartość zwracana mainpunktu wejścia.
Vern DeHaven
źródło
Czy twój pierwszy punkt dotyczący C # 6 może zostać zweryfikowany? Nie mogę znaleźć niczego online. Zwracana wartość z funkcji Main jest dołączona do kodu zakończenia procesu (przynajmniej we wszystkich poprzednich kompilatorach), dlaczego mieliby to zmienić?
Arman McHitarian
Czysto anegdotyczne dowody, ale właśnie natknąłem się na to we własnej bibliotece, w której po prostu zwrot mojego kodu wyniku / błędu Main()nie ustawił tego, Process.ExitCodeco widzi aplikacja wywołująca.
Marcus Mangelsdorf,
MSDN twierdzi, że int Mainnadal może być używany jako alternatywa dla Environment.ExitCode. link
Arman McHitarian,
Mam aplikację, która uruchamia wiele wątków. W niektórych okolicznościach muszę zamknąć niektóre wątki za pomocą Thread.Abort () przed wyjściem z aplikacji. W tych okolicznościach int Main () {... thread.Abort (); ... zwraca 0;} NIE powoduje, że kod zakończenia procesu wynosi 0: kod zakończenia procesu to -1. Wydaje się, że w pewnych okolicznościach MS zdecydowało, że konwencja polegająca na użyciu wartości zwracanej z głównego wątku do ustawienia kodu zakończenia procesu nie jest dla nich wystarczająco dobra. Szczerze mówiąc, może to być problem z czasem: przerwanie wątku może spowodować ustawienie kodu wyjścia bardzo późno w grze.
David I. McIntosh,
7

Opcja wyliczenia jest doskonała, ale można ją ulepszyć, mnożąc liczby jak w:

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

W przypadku wielu błędów, dodanie określonych numerów błędów razem daje unikalny numer, który będzie reprezentował kombinację wykrytych błędów.

Na przykład poziom błędu 6 może składać się tylko z błędów 4 i 2, 12 może składać się tylko z błędów 4 i 8, 14 może składać się tylko z 2, 4 i 8 itd.

David
źródło
2
Dzieje się tak, jeśli po znalezieniu jednego z nich starasz się sprawdzić, czy nie ma dalszych błędów. Większość aplikacji nie.
Nyerguds
3

Moje 2 centy:

Systemowe kody błędów można znaleźć tutaj: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

Znajdziesz typowe kody, takie jak 2 dla „nie znaleziono pliku” lub 5 dla „odmowy dostępu”.

A kiedy natkniesz się na nieznany kod, możesz użyć tego polecenia, aby dowiedzieć się, co to znaczy:

net helpmsg decimal_code

na przykład

pomoc netto 1

zwroty

Niepoprawna funkcja

Fred Mauroy
źródło
0

Użyj tego kodu

Environment.Exit(0);

użyj 0 jako int, jeśli nie chcesz niczego zwracać.

Swastik Bhattacharyya
źródło
To nie odpowiada na pytanie OP, a zwrócenie 0 oznacza zwrot czegoś ...
PL