Como especifico o código de saída de um aplicativo de console no .NET?

471

Eu tenho um aplicativo de console trivial no .NET. É apenas uma parte de teste de um aplicativo maior. Gostaria de especificar o "código de saída" do meu aplicativo de console. Como eu faço isso?

MrDatabase
fonte

Respostas:

599

3 opções:

  • Você pode devolvê-lo Mainse declarar seu Mainmétodo para retornar int.
  • Você pode ligar Environment.Exit(code).
  • Você pode definir o código de saída usando propriedades: Environment.ExitCode = -1;. Isso será usado se nada mais definir o código de retorno ou usar uma das outras opções acima).

Dependendo do seu aplicativo (console, serviço, aplicativo da web etc.), diferentes métodos podem ser usados.

TheSoftwareJedi
fonte
12
Para aqueles que se perguntam por que isso não funciona no caso deles, verifique se o seu projeto foi compilado como um "aplicativo de console" e não como um "aplicativo do Windows".
Marcel Gosselin
9
e se eu tiver um aplicativo WinForms que, com alguns argumentos, quero que ele se comporte como um aplicativo de console?
sebagomez 7/09/12
5
Você também pode digitar o programa maine como int (substituir void por int) e usar, por exemplo, "return -1;" para retornar do programa principal. Isso é mais portátil que Environment.Exit () (que depende do ambiente).
Werner
14
@DannyBeckett Por convenção, um código de saída 0significa sucesso e diferente de zero significa falha. return;indica sucesso através do código de saída 0e return -1;indica falha.
allonhadaya
6
Você também pode definir o código de saída usando as propriedades: Environment.ExitCode = -1;
t3b4n 31/08/16
270

Além das respostas que cobrem as int retorno ... um pedido de sanidade. Por favor, defina seus códigos de saída em uma enumeração, com Bandeiras, se apropriado. Isso facilita muito a depuração e a manutenção (e, como bônus, você pode imprimir facilmente os códigos de saída na tela de ajuda - você possui um desses, certo?).

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

int Main(string[] args) {
   return (int)ExitCode.Success;
}
Mark Brackett
fonte
46
Você pode adicionar que o valor de "0" para "Sucesso" não é por acaso, mas na verdade o valor "padrão" para essa situação.
Christian.K
39
ISTO. É por isso que SO é o melhor site da história da internet. Esse conselho não está prontamente disponível em nenhum livro didático e só pode ser obtido conversando com um profissional experiente. OBRIGADO.
Daniel Szabo
17
Você diz que 0 é o valor padrão para o sucesso e, ao converter 0/1 em booleano, 0 é falso e 1 é verdadeiro! Pode ser mais preciso dizer que um código de saída 0 significa "sem erro", em vez de "êxito", pois o código de saída é um ErrorResult e não simplesmente um Resultado.
Mark Shapiro
11
Para obter a lista completa das convenções da Microsoft, consulte msdn.microsoft.com/en-us/library/windows/desktop/… . Um cara fez uma lista enorme de consts e a usou em um caso de troca nos comentários mais abaixo.
Nawfal
5
@ MarkShapiro, eu acho que 0 = Successvem do fato de haver apenas um código de sucesso necessário, mas muitos códigos de erro, como 0, como não tendo + ou - em números inteiros de computador, podem ser usados ​​para identificar exclusivamente o sucesso
Sebastian
49

Existem três métodos que você pode usar para retornar um código de saída de um aplicativo de console.

  1. Modifique o Mainmétodo no seu aplicativo para que ele retorne um em intvez de void(uma função que retorna um em Integervez de Subno VB.Net) e, em seguida, retorne o código de saída desse método.
  2. Defina a propriedade Environment.ExitCode como o código de saída. Observe que o método 1. tem precedência - se o Mainmétodo retornar algo diferente de void(é um Subno VB.Net), o valor dessa propriedade será ignorado.
  3. Passe o código de saída para o método Environment.Exit . Isso encerrará o processo imediatamente, em oposição aos outros dois métodos.

Um padrão importante que deve ser observado é o que 0representa 'Sucesso'.

Em um tópico relacionado, considere usar uma enumeração para definir os códigos de saída que seu aplicativo retornará. O FlagsAttribute permitirá que você retorne uma combinação de códigos.

Além disso, verifique se seu aplicativo é compilado como um 'Aplicativo de console'.

Scott Munro
fonte
1
Isso traz um ponto interessante. Definição de Environment.ExitCodenão fechar o programa imediatamente, mas Environment.Exitmétodo fecha o programa imediatamente
PsychoData
1
O código de saída também funciona em aplicativos do Windows. Se o aplicativo for iniciado a partir do c #, por meio de um Processobjeto, você poderá solicitar o objeto WaitForExit()e solicitar o código de saída.
Nyerguds
43

Se você vai usar o método sugerido por David, também deve dar uma olhada no atributo [Flags].

Isso permite que você faça operações inteligentes em enumerações.

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

Então

(ExitCodes.SignFailed | ExitCodes.UnknownError)

seria 16 + 32. :)

Aron Tsang
fonte
3
Isso implica que um programa diga 'sua senha está errada' e tente assinar o que estiver assinando e só pare se falhar. Você deve retornar quando falhar; qualquer outra coisa é um aviso e o programa ainda deve retornar 0.
Pete Kirkham
3
Pouco fato conhecido é que [Flags] não faz nada para ativar ou desativar operações bit a bit. Tudo o que faz é substituir o método ToString para que a saída represente os sinalizadores bit a bit. Com ou sem ele, você ainda pode executar operações bit a bit.
21316 Steven
3
@ Steven, é bom saber, mas eu ainda recomendo enums de decoração destinadas ao "uso da bandeira" com esse atributo, se nada mais transmitir a intenção.
MarioDS 7/11
25
int code = 2;
Environment.Exit( code );
cavalo pálido
fonte
17
Qualquer motivo técnico, você não escreveu apenas "Environment.Exit (2);" ?
Blorgbeard sai em 30/09/08
52
Atribuir um número mágico a uma variável com um nome sem sentido não a torna menos mágica.
Blorgbeard sai
11

Basta retornar o código apropriado de main.

int main(string[] args)
{
      return 0; //or exit code of your choice
}
Esteban Araya
fonte
2
O aplicativo de console C # padrão não declara principal. Declara static void Main(string[] args);
Mark Lakata
19
@ Mark Lakta: Então mude, não?
Esteban Araya
11

Use ExitCode se o seu principal tiver uma assinatura de retorno nula; caso contrário, você precisará "configurá-la" pelo valor retornado.

Propriedade Environment.ExitCode

Se o método Main retornar nulo, você poderá usar esta propriedade para definir o código de saída que será retornado ao ambiente de chamada. Se Main não retornar nulo, essa propriedade será ignorada. O valor inicial desta propriedade é zero.

crashmstr
fonte
8

Como atualização da resposta de Scott Munro :

  • No C # 6.0 e no VB.NET 14.0 (VS 2015), é necessário o Environment.ExitCode ou o Environment.Exit (exitCode) para retornar um código diferente de zero de um aplicativo de console. Alterar o tipo de retorno de Mainnão tem efeito.
  • No F # 4.0 (VS 2015), o valor de retorno do mainponto de entrada é respeitado.
Vern DeHaven
fonte
Seu 1º ponto em relação ao C # 6 pode ser verificado? Não consigo encontrar nada online. O valor de retorno da função Main é anexado ao código de saída do processo (pelo menos em todos os compiladores anteriores), por que eles deveriam ter mudado isso?
Arman McHitarian 27/10/16
Evidência anedótica pura, mas acabei de encontrar isso em minha própria biblioteca, onde simplesmente retornar meu código de resultado / erro de Main()não definiu o Process.ExitCodevisto pelo aplicativo de chamada.
Marcus Mangelsdorf
O MSDN afirma que int Mainainda pode ser usado como uma alternativa ao Environment.ExitCode. link
Arman McHitarian 2/16
Eu tenho um aplicativo que executa vários threads. Em certas circunstâncias, preciso bloquear alguns threads via Thread.Abort (), antes de sair do aplicativo. Nessas circunstâncias, int Main () {... thread.Abort (); ... return 0;} NÃO resulta em um código de saída do processo 0: o código de saída do processo é -1. Parece que em certas circunstâncias, a MS decidiu que a convenção de usar o valor de retorno do thread principal para definir o código de saída do processo não é suficiente para eles. Para ser justo, pode ser um problema de tempo: a interrupção do encadeamento pode estar definindo o código de saída muito tarde no jogo.
David I. McIntosh
7

A opção de enumeração é excelente, mas pode ser aprimorada multiplicando os números como em:

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

No caso de vários erros, a adição de números de erros específicos fornecerá um número único que representará a combinação dos erros detectados.

Por exemplo, um nível de erro 6 pode consistir apenas nos erros 4 e 2, 12 pode consistir apenas nos erros 4 e 8, 14 só pode consistir em 2, 4 e 8 etc.

David
fonte
2
Ou seja, se você se incomodar em verificar outros erros após encontrar um, no entanto. A maioria dos aplicativos não.
precisa saber é o seguinte
3

Meus 2 centavos:

Você pode encontrar os códigos de erro do sistema aqui: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

Você encontrará os códigos típicos como 2 para "arquivo não encontrado" ou 5 para "acesso negado".

E quando você encontra um código desconhecido, pode usar este comando para descobrir o que significa:

net helpmsg decimal_code

por exemplo

net helpmsg 1

retorna

Função incorreta

Fred Mauroy
fonte
0

Use este código

Environment.Exit(0);

use 0 como int se você não quiser retornar nada.

Swastik Bhattacharyya
fonte
Isso não está respondendo à pergunta do OP e retornando 0 está retornando algo ...
PL