¿Cómo especifico el código de salida de una aplicación de consola en .NET?

471

Tengo una aplicación de consola trivial en .NET. Es solo una parte de prueba de una aplicación más grande. Me gustaría especificar el "código de salida" de mi aplicación de consola. ¿Cómo hago esto?

MrDatabase
fuente

Respuestas:

599

3 opciones:

  • Puede devolverlo Mainsi declara su Mainmétodo de devolución int.
  • Puede llamar Environment.Exit(code).
  • Puede establecer el código de salida mediante las propiedades: Environment.ExitCode = -1;. Esto se usará si nada más establece el código de retorno o usa una de las otras opciones anteriores).

Dependiendo de su aplicación (consola, servicio, aplicación web, etc.) se pueden usar diferentes métodos.

TheSoftwareJedi
fuente
12
Para aquellos de ustedes que se preguntan por qué esto no funciona en su caso, asegúrese de que su proyecto esté compilado como una "aplicación de consola" y no como una "aplicación de Windows".
Marcel Gosselin
10
¿Qué pasa si tengo una aplicación WinForms que con algunos argumentos quiero que se comporte como una aplicación de consola?
sebagomez
55
También puede escribir el programa principal como int (reemplazar void por int) y usar, por ejemplo, "return -1;" para volver del programa principal. Esto es más portátil que Environment.Exit () (que depende del entorno).
werner
14
@DannyBeckett Por convención, un código de salida 0significa éxito y no cero significa error. return;indica éxito a través del código de salida 0e return -1;indica falla.
allonhadaya
66
También puede establecer el código de salida usando las propiedades: Environment.ExitCode = -1;
t3b4n
270

Además de las respuestas que cubren el retorno int ... una súplica por cordura. Por favor, defina sus códigos de salida en una enumeración, con Banderas si corresponde. Hace que la depuración y el mantenimiento sean mucho más fáciles (y, como beneficio adicional, puede imprimir fácilmente los códigos de salida en la pantalla de ayuda; tiene uno de esos, ¿verdad?).

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

int Main(string[] args) {
   return (int)ExitCode.Success;
}
Mark Brackett
fuente
46
Es posible que desee agregar que el valor de "0" para "Éxito" no es una casualidad, sino el valor "estándar" para esa situación.
Christian.K
39
ESTA. Es por eso que SO es el mejor sitio web en la historia de Internet. Este consejo no está disponible en ningún libro de texto, y solo se puede obtener hablando con un profesional experimentado. GRACIAS.
Daniel Szabo
17
Usted dice que 0 es el valor estándar para el éxito y, sin embargo, al convertir 0/1 a booleano, ¡0 es falso y 1 es verdadero! Puede ser más exacto decir que un código de salida de 0 significa "sin error", en lugar de "éxito", ya que el código de salida es un ErrorResult y no simplemente un Resultado.
Mark Shapiro
11
Para ver la lista completa de la convención de microsoft, consulte msdn.microsoft.com/en-us/library/windows/desktop/… . Algún tipo ha hecho una gran lista de concursos y la usó en un caso de cambio en los comentarios más abajo.
nawfal
55
@ MarkShapiro, supongo que 0 = Successproviene del hecho de que solo se necesita un código de éxito, pero se pueden usar muchos códigos de error, como 0, que no tiene + o - en los enteros de la computadora, para identificar el éxito de manera única
Sebastian
50

Hay tres métodos que puede usar para devolver un código de salida de una aplicación de consola.

  1. Modifique el Mainmétodo en su aplicación para que devuelva un en intlugar de void(una función que devuelve un en Integerlugar de Suben VB.Net) y luego devuelva el código de salida de ese método.
  2. Establezca la propiedad Environment.ExitCode en el código de salida. Tenga en cuenta que el método 1. tiene prioridad: si el Mainmétodo devuelve algo que no sea void(es a Suben VB.Net), el valor de esta propiedad se ignorará.
  3. Pase el código de salida al método Environment.Exit . Esto terminará el proceso inmediatamente en lugar de los otros dos métodos.

Un estándar importante que debe observarse es que 0representa el "éxito".

En un tema relacionado, considere usar una enumeración para definir los códigos de salida que su aplicación va a devolver. El FlagsAttribute le permitirá volver una combinación de códigos.

Además, asegúrese de que su aplicación se compila como una 'Aplicación de consola'.

Scott Munro
fuente
1
Esto trae a colación un punto interesante. La configuración Environment.ExitCodeno cierra el programa de inmediato, pero el Environment.Exitmétodo lo cierra de inmediato
PsychoData
1
El código de salida también funciona en aplicaciones de Windows. Si la aplicación se iniciara desde c #, a través de un Processobjeto, puede solicitarle el objeto WaitForExit()y luego solicitarle el código de salida.
Nyerguds
43

Si va a utilizar el método sugerido por David, también debe echar un vistazo al Atributo [Banderas].

Esto le permite realizar operaciones poco sabias en las enumeraciones.

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

Entonces

(ExitCodes.SignFailed | ExitCodes.UnknownError)

sería 16 + 32. :)

Aron Tsang
fuente
3
Esto implica que un programa diría 'su contraseña es incorrecta' y luego intentará firmar lo que sea que esté firmando, y solo se detendrá si luego falla. Deberías regresar una vez que hayas fallado; cualquier otra cosa es una advertencia y el programa aún debería devolver 0.
Pete Kirkham
3
Un hecho poco conocido es que [Flags] no hace nada para habilitar o deshabilitar las operaciones bit a bit. Todo lo que hace es anular el método ToString para que la salida represente los indicadores bit a bit. Con o sin él, aún puede realizar operaciones bit a bit.
Steven
3
@Steven, es bueno saberlo, pero aún así recomendaría decorar enumeraciones destinadas al "uso de la bandera" con ese atributo, si nada más transmite intención.
MarioDS
25
int code = 2;
Environment.Exit( code );
caballo pálido
fuente
17
Cualquier motivo técnico por el que no haya escrito simplemente "Environment.Exit (2);" ?
Blorgbeard sale el
53
Asignar un número mágico a una variable con un nombre sin sentido no lo hace menos mágico.
Blorgbeard sale el
11

Simplemente devuelva el código apropiado de main.

int main(string[] args)
{
      return 0; //or exit code of your choice
}
Esteban Araya
fuente
2
La aplicación de consola predeterminada de C # no declara main en absoluto. Declara static void Main(string[] args);
Mark Lakata
19
@ Mark Lakta: Entonces cámbialo, ¿no?
Esteban Araya
11

Utilice ExitCode si su principal tiene una firma de devolución nula, de lo contrario, debe "establecerla" por el valor que devuelve.

Propiedad Environment.ExitCode

Si el método Main devuelve void, puede usar esta propiedad para establecer el código de salida que se devolverá al entorno de llamada. Si Main no devuelve void, esta propiedad se ignora. El valor inicial de esta propiedad es cero.

crashmstr
fuente
8

Como una actualización de la respuesta de Scott Munro :

  • En C # 6.0 y VB.NET 14.0 (VS 2015), se requiere Environment.ExitCode o Environment.Exit (exitCode) para devolver un código distinto de cero desde una aplicación de consola. Cambiar el tipo de retorno deMain no tiene ningún efecto.
  • En F # 4.0 (VS 2015), mainse respeta el valor de retorno del punto de entrada.
Vern DeHaven
fuente
¿Se puede verificar su primer punto con respecto a C # 6? Parece que no puedo encontrar nada en línea. El valor de retorno de la función Main se adjunta al código de salida del proceso (al menos en todos los compiladores anteriores), ¿por qué deberían haber cambiado eso?
Arman McHitarian
Evidencia anecdótica pura, pero acabo de encontrar esto en mi propia biblioteca, donde simplemente devolver mi código de resultado / error Main()no configuró el Process.ExitCodeque ve la aplicación de llamada.
Marcus Mangelsdorf
MSDN afirma int Mainque todavía se puede usar como una alternativa a Environment.ExitCode. enlace
Arman McHitarian
Tengo una aplicación que ejecuta múltiples hilos. En ciertas circunstancias, necesito bloquear algunos hilos a través de Thread.Abort (), antes de salir de la aplicación. En estas circunstancias, int Main () {... thread.Abort (); ... return 0;} NO da como resultado un código de salida del proceso de 0: el código de salida del proceso es -1. Parece que, en ciertas circunstancias, MS ha decidido que la convención de usar el valor de retorno del hilo principal para establecer el código de salida del proceso no es lo suficientemente bueno para ellos. Para ser justos, podría ser un problema de tiempo: el aborto del hilo podría estar configurando el código de salida muy tarde en el juego.
David I. McIntosh
7

La opción de enumeración es excelente, sin embargo, puede mejorarse multiplicando los números como en:

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

En el caso de múltiples errores, agregar los números de error específicos juntos le dará un número único que representará la combinación de errores detectados.

Por ejemplo, un nivel de error de 6 solo puede consistir en los errores 4 y 2, 12 solo puede consistir en los errores 4 y 8, 14 solo puede consistir en 2, 4 y 8, etc.

David
fuente
2
Sin embargo, eso es si te molestas en buscar más errores después de encontrar uno. La mayoría de las aplicaciones no lo hacen.
Nyerguds
3

Mis 2 centavos:

Puede encontrar los códigos de error del sistema aquí: https://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx

Encontrará los códigos típicos como 2 para "archivo no encontrado" o 5 para "acceso denegado".

Y cuando te topas con un código desconocido, puedes usar este comando para descubrir lo que significa:

net helpmsg decimal_code

p.ej

ayuda neta 1

devoluciones

Función incorrecta

Fred Mauroy
fuente
0

Usa este código

Environment.Exit(0);

use 0 como int si no desea devolver nada.

Swastik Bhattacharyya
fuente
Esto no responde la pregunta de OP y devolver 0 es devolver algo ...
PL