Partager via


Main() et arguments de ligne de commande

La méthode Main est le point d’entrée d’une application C#. Lorsque l’application est démarrée, la méthode Main est la première méthode appelée.

Il ne peut y avoir qu’un seul point d’entrée dans un programme C#. Si plusieurs classes ont une méthode Main, vous devez compiler votre programme avec l’option de compilateur StartupObject pour spécifier quelle méthode Main utiliser comme point d’entrée. Pour plus d’informations, consultez StartupObject (Options du compilateur C#). L’exemple suivant affiche le nombre d’arguments de ligne de commande comme première action :

class TestClass
{
    static void Main(string[] args)
    {
        Console.WriteLine(args.Length);
    }
}

Vous pouvez également utiliser des instructions de niveau supérieur dans un fichier comme point d’entrée pour votre application. Tout comme la méthode Main, les instructions de niveau supérieur peuvent également retourner des valeurs et accéder aux arguments de ligne de commande. Pour plus d’informations, consultez Instructions de niveau supérieur. L’exemple suivant utilise une foreach boucle pour afficher les arguments de ligne de commande à l’aide de la args variable, et à la fin du programme retourne un code de réussite (0) :

using System.Text;

StringBuilder builder = new();
builder.AppendLine("The following arguments are passed:");

foreach (var arg in args)
{
    builder.AppendLine($"Argument={arg}");
}

Console.WriteLine(builder.ToString());

return 0;

À compter de C# 14, les programmes peuvent être des programmes basés sur des fichiers, où un seul fichier contient le programme. Vous exécutez des programmes basés sur des fichiers avec la commande dotnet run <file.cs>ou en utilisant la #!/usr/local/share/dotnet/dotnet run directive comme première ligne (shells unix uniquement).

Vue d’ensemble

  • La Main méthode est le point d’entrée d’un programme exécutable ; c’est là que le contrôle de programme démarre et se termine.
  • Main doit être déclarée dans une classe ou un struct. L'élément englobant class peut être static.
  • Main doit être static.
  • Main peut avoir n’importe quel modificateur d’accès (à l’exception de file).
  • Main peut avoir le type de retour void, int, Task, ou Task<int>.
  • Si et seulement si Main retourne une Task ou Task<int>, la déclaration de Main peut inclure le async modificateur. Cette règle exclut spécifiquement une async void Main méthode.
  • La méthode Main peut être déclarée avec ou sans paramètre string[], qui contient des arguments de ligne de commande. Lorsque vous utilisez Visual Studio pour créer des applications Windows, vous pouvez ajouter le paramètre manuellement ou bien utiliser la méthode GetCommandLineArgs() pour obtenir les arguments de ligne de commande. Les paramètres sont lus comme des arguments de ligne de commande avec index de base zéro. Contrairement à C et C++, le nom du programme n’est pas traité comme le premier argument de ligne de commande dans le args tableau, mais il s’agit du premier élément de la GetCommandLineArgs() méthode.

La liste suivante présente les déclarations Main les plus courantes :

static void Main() { }
static int Main() { }
static void Main(string[] args) { }
static int Main(string[] args) { }
static async Task Main() { }
static async Task<int> Main() { }
static async Task Main(string[] args) { }
static async Task<int> Main(string[] args) { }

Les exemples précédents ne spécifient pas de modificateur d’accès. Ils sont donc implicitement private par défaut. Il est possible de spécifier n’importe quel modificateur d’accès explicite.

Conseil

L’ajout des types de retour async et Task, Task<int> simplifie le code de programme lorsque les applications de console doivent démarrer et await des opérations asynchrones dans Main.

Valeurs de retour Main()

Vous pouvez renvoyer un int à la méthode Main en définissant la méthode de l’une des manières suivantes :

Déclaration Main Code de la méthode Main
static int Main() Aucune utilisation de args ou await
static int Main(string[] args) Utilise args, mais pas await
static async Task<int> Main() Utilise await, mais pas args
static async Task<int> Main(string[] args) Utilise args et await

Si la valeur de retour de Main n’est pas utilisée, retourne void ou Task autorise un code légèrement plus simple.

Déclaration Main Code de la méthode Main
static void Main() Aucune utilisation de args ou await
static void Main(string[] args) Utilise args, mais pas await
static async Task Main() Utilise await, mais pas args
static async Task Main(string[] args) Utilise args et await

Cependant, retourner int ou Task<int> permet au programme de communiquer des informations d’état à d’autres programmes ou scripts qui appellent le fichier exécutable.

L’exemple suivant montre comment accéder au code de sortie du processus.

Cet exemple utilise les outils de ligne de commande .NET Core. Si vous ne connaissez pas les outils en ligne de commande .NET Core, vous pouvez en savoir plus dans cet article de prise en main.

Créez une application en exécutant dotnet new console. Modifiez la méthode Main dans Program.cs comme suit :

class MainReturnValTest
{
    static int Main()
    {
        //...
        return 0;
    }
}

N’oubliez pas d’enregistrer ce programme en tant que MainReturnValTest.cs.

Quand un programme est exécuté dans Windows, toute valeur retournée par la fonction Main est stockée dans une variable d’environnement. Cette variable d’environnement peut être récupérée à l’aide de ERRORLEVEL dans un fichier de commandes ou de $LastExitCode dans PowerShell.

Vous pouvez générer l’application à l’aide de la commande dotnet CLIdotnet build.

Ensuite, créez un script PowerShell pour exécuter l’application et afficher le résultat. Collez le code suivant dans un fichier texte et enregistrez-le sous test.ps1 dans le dossier qui contient le projet. Exécutez le script PowerShell en tapant test.ps1 à l’invite de PowerShell.

Étant donné que le code retourne zéro, le fichier batch signale la réussite. Toutefois, si vous modifiez MainReturnValTest.cs pour retourner une valeur différente de zéro, puis recompiler le programme, l’exécution ultérieure du script PowerShell signale l’échec.

dotnet run
if ($LastExitCode -eq 0) {
    Write-Host "Execution succeeded"
} else
{
    Write-Host "Execution Failed"
}
Write-Host "Return value = " $LastExitCode
Execution succeeded
Return value = 0

Valeurs de retour d’Async Main

Lorsque vous déclarez une async valeur de retour pour Main, le compilateur génère le code réutilisable pour appeler des méthodes asynchrones dans Main:

class Program
{
    static async Task<int> Main(string[] args)
    {
        return await AsyncConsoleWork();
    }

    private static async Task<int> AsyncConsoleWork()
    {
        return 0;
    }
}

Dans les deux exemples, le corps principal du programme se trouve dans le corps de la méthode AsyncConsoleWork().

L’avantage de déclarerMain comme async est que le compilateur génère toujours un code correct.

Quand le point d’entrée de l’application retourne Task ou Task<int>, le compilateur génère un nouveau point d’entrée qui appelle la méthode de point d’entrée déclarée dans le code d’application. En supposant que ce point d’entrée est appelé $GeneratedMain, le compilateur génère le code suivant pour ces points d’entrée :

  • static Task Main() permet au compilateur d’émettre l’équivalent de private static void $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task Main(string[]) permet au compilateur d’émettre l’équivalent de private static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
  • static Task<int> Main() permet au compilateur d’émettre l’équivalent de private static int $GeneratedMain() => Main().GetAwaiter().GetResult();
  • static Task<int> Main(string[]) permet au compilateur d’émettre l’équivalent de private static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();

Remarque

Si les exemples ont utilisé le modificateur async sur la méthode Main, le compilateur génère le même code.

Arguments de ligne de commande

Vous pouvez envoyer des arguments à la méthode Main en définissant la méthode de l’une des manières suivantes :

Déclaration Main Code de la méthode Main
static void Main(string[] args) Aucune valeur de retour ou await
static int Main(string[] args) Retourne une valeur, mais n’utilise pas await
static async Task Main(string[] args) Utilise await mais ne retourne pas de valeur
static async Task<int> Main(string[] args) Retourner une valeur et utiliser await

Si les arguments ne sont pas utilisés, vous pouvez omettre args de la déclaration de méthode pour un code légèrement plus simple :

Déclaration Main Code de la méthode Main
static void Main() Aucune valeur de retour ou await
static int Main() Retourne une valeur, mais n’utilise pas await
static async Task Main() Utilise await mais ne retourne pas de valeur
static async Task<int> Main() Retourne une valeur et utilise await

Remarque

Vous pouvez également utiliser Environment.CommandLine ou Environment.GetCommandLineArgs pour accéder aux arguments de ligne de commande à partir de n’importe quel emplacement d’une application console ou Windows Forms. Pour activer les arguments de ligne de commande dans la déclaration de méthode Main dans une application Windows Forms, vous devez modifier manuellement la déclaration de Main. Le code généré par Windows Forms crée Main sans paramètre d’entrée.

Le paramètre de la méthode Main est un tableau String qui représente les arguments de ligne de commande. En général, vous déterminez s’il existe des arguments en testant la propriété Length, par exemple :

if (args.Length == 0)
{
    System.Console.WriteLine("Please enter a numeric argument.");
    return 1;
}

Conseil

Le tableau args ne peut pas être null. Par conséquent, il est sûr d’accéder à la propriété Length sans vérification de la valeur Null.

Vous pouvez également convertir les arguments de chaîne en types numériques à l’aide de la classe Convert ou de la méthode Parse. Par exemple, l’instruction suivante convertit string en nombre long en utilisant la méthode Parse :

long num = Int64.Parse(args[0]);

Il est également possible d’utiliser le type long, qui est un alias de Int64.

long num = long.Parse(args[0]);

Vous pouvez également utiliser la méthode Convert de la classe ToInt64 pour obtenir le même résultat :

long num = Convert.ToInt64(s);

Pour plus d’informations, consultez Parse et Convert.

Conseil

L’analyse des arguments de ligne de commande peut être complexe. Envisagez d’utiliser la bibliothèque System.CommandLine (actuellement en version bêta) pour simplifier le processus.

L’exemple suivant montre comment utiliser des arguments de ligne de commande dans une application console. L’application prend un argument au moment de l’exécution, le convertit en entier, puis calcule la factorielle du nombre. Si aucun argument n’est fourni, l’application affiche un message pour expliquer comment le programme doit être utilisé.

Pour compiler et exécuter l’application à partir d’une invite de commandes, procédez comme suit :

  1. Collez le code suivant dans un éditeur de texte, puis enregistrez le fichier en tant que fichier texte sous le nom Factorial.cs.

    public class Functions
    {
        public static long Factorial(int n)
        {
            // Test for invalid input.
            if ((n < 0) || (n > 20))
            {
                return -1;
            }
    
            // Calculate the factorial iteratively rather than recursively.
            long tempResult = 1;
            for (int i = 1; i <= n; i++)
            {
                tempResult *= i;
            }
            return tempResult;
        }
    }
    
    class MainClass
    {
        static int Main(string[] args)
        {
            if (args.Length == 0)
            {
                Console.WriteLine("Please enter a numeric argument.");
                Console.WriteLine("Usage: Factorial <num>");
                return 1;
            }
    
            int num;
            bool test = int.TryParse(args[0], out num);
            if (!test)
            {
                Console.WriteLine("Please enter a numeric argument.");
                Console.WriteLine("Usage: Factorial <num>");
                return 1;
            }
    
            long result = Functions.Factorial(num);
    
            if (result == -1)
                Console.WriteLine("Input must be >= 0 and <= 20.");
            else
                Console.WriteLine($"The Factorial of {num} is {result}.");
    
            return 0;
        }
    }
    

    Au début de la méthode Main, le programme teste si les arguments d’entrée n’ont pas été fournis en comparant la longueur de l’argument args à 0. Il affiche l’aide, si aucun argument n’est trouvé.
    Si des arguments sont fournis (args.Length est supérieur à 0), le programme tente de convertir les arguments d’entrée en nombres. Cet exemple lève une exception si l’argument n’est pas un nombre.
    Une fois la factorielle calculée (stockée dans une variable result de type long), le résultat détaillé est imprimé en fonction de la variable result.

  2. Dans l’écran Démarrer ou le menu Démarrer, ouvrez une fenêtre Invite de commandes développeur Visual Studio, puis accédez au dossier qui contient le fichier que vous avez créé.

  3. Pour compiler l’application, entrez la commande suivante :

    dotnet build

    Si votre application n’a aucune erreur de compilation, un fichier binaire nommé Factorial.dll est créé.

  4. Entrez la commande suivante pour calculer la factorielle de 3 :

    dotnet run -- 3

  5. Si 3 est entré sur la ligne de commande en tant qu’argument du programme, la sortie lit : The factorial of 3 is 6.

Remarque

Quand vous exécutez une application dans Visual Studio, vous pouvez spécifier des arguments de ligne de commande dans la page Débogage du Concepteur de projet.

spécification du langage C#

Pour plus d'informations, voir la spécification du langage C#. La spécification du langage est la source de référence pour la syntaxe C# et son utilisation.

Voir aussi