¿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?

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.


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;
}

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'.


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. :)


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



11

Simplemente devuelva el código apropiado de main.

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

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.


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.

¿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.


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


0

Usa este código

Environment.Exit(0);

use 0 como int si no desea devolver nada.


Esto no responde la pregunta de OP y devolver 0 es devolver algo ...
PL
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.