Write a 'main' Method That Examines Its Command-line Arguments and
This browser is no longer supported.
Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.
- Feedback
- Edit
Main() and command-line arguments
- Article
- 9 minutes to read
-
Thank you.
The Main
method is the entry point of a C# application. (Libraries and services do not require a Main
method as an entry point.) When the application is started, the Main
method is the first method that is invoked.
There can only be one entry point in a C# program. If you have more than one class that has a Main
method, you must compile your program with the StartupObject compiler option to specify which Main
method to use as the entry point. For more information, see StartupObject (C# Compiler Options).
using System; class TestClass { static void Main(string[] args) { // Display the number of command line arguments. Console.WriteLine(args.Length); } }
Starting in C# 9, you can omit the Main
method, and write C# statements as if they were in the Main
method, as in the following example:
using System.Text; StringBuilder builder = new(); builder.AppendLine("Hello"); builder.AppendLine("World!"); Console.WriteLine(builder.ToString());
For information about how to write application code with an implicit entry point method, see Top-level statements.
Overview
- The
Main
method is the entry point of an executable program; it is where the program control starts and ends. -
Main
is declared inside a class or struct.Main
must bestatic
and it need not bepublic
. (In the earlier example, it receives the default access ofprivate
.) The enclosing class or struct is not required to be static. -
Main
can either have avoid
,int
, or, starting with C# 7.1,Task
, orTask<int>
return type. - If and only if
Main
returns aTask
orTask<int>
, the declaration ofMain
may include theasync
modifier. This specifically excludes anasync void Main
method. - The
Main
method can be declared with or without astring[]
parameter that contains command-line arguments. When using Visual Studio to create Windows applications, you can add the parameter manually or else use the GetCommandLineArgs() method to obtain the command-line arguments. Parameters are read as zero-indexed command-line arguments. Unlike C and C++, the name of the program is not treated as the first command-line argument in theargs
array, but it is the first element of the GetCommandLineArgs() method.
The following list shows valid Main
signatures:
public static void Main() { } public static int Main() { } public static void Main(string[] args) { } public static int Main(string[] args) { } public static async Task Main() { } public static async Task<int> Main() { } public static async Task Main(string[] args) { } public static async Task<int> Main(string[] args) { }
The preceding examples all use the public
accessor modifier. That's typical, but not required.
The addition of async
and Task
, Task<int>
return types simplifies program code when console applications need to start and await
asynchronous operations in Main
.
Main() return values
You can return an int
from the Main
method by defining the method in one of the following ways:
Main method code | Main signature |
---|---|
No use of args or await | static int Main() |
Uses args , no use of await | static int Main(string[] args) |
No use of args , uses await | static async Task<int> Main() |
Uses args and await | static async Task<int> Main(string[] args) |
If the return value from Main
is not used, returning void
or Task
allows for slightly simpler code.
Main method code | Main signature |
---|---|
No use of args or await | static void Main() |
Uses args , no use of await | static void Main(string[] args) |
No use of args , uses await | static async Task Main() |
Uses args and await | static async Task Main(string[] args) |
However, returning int
or Task<int>
enables the program to communicate status information to other programs or scripts that invoke the executable file.
The following example shows how the exit code for the process can be accessed.
This example uses .NET Core command-line tools. If you are unfamiliar with .NET Core command-line tools, you can learn about them in this get-started article.
Create a new application by running dotnet new console
. Modify the Main
method in Program.cs as follows:
// Save this program as MainReturnValTest.cs. class MainReturnValTest { static int Main() { //... return 0; } }
When a program is executed in Windows, any value returned from the Main
function is stored in an environment variable. This environment variable can be retrieved using ERRORLEVEL
from a batch file, or $LastExitCode
from PowerShell.
You can build the application using the dotnet CLI dotnet build
command.
Next, create a PowerShell script to run the application and display the result. Paste the following code into a text file and save it as test.ps1
in the folder that contains the project. Run the PowerShell script by typing test.ps1
at the PowerShell prompt.
Because the code returns zero, the batch file will report success. However, if you change MainReturnValTest.cs to return a non-zero value and then recompile the program, subsequent execution of the PowerShell script will report failure.
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
Async Main return values
When you declare an async
return value for Main
, the compiler generates the boilerplate code for calling asynchronous methods in Main
. If you don't specify the async
keyword, you need to write that code yourself, as shown in the following example. The code in the example ensures that your program runs until the asynchronous operation is completed:
public static void Main() { AsyncConsoleWork().GetAwaiter().GetResult(); } private static async Task<int> AsyncConsoleWork() { // Main body here return 0; }
This boilerplate code can be replaced by:
static async Task<int> Main(string[] args) { return await AsyncConsoleWork(); }
An advantage of declaring Main
as async
is that the compiler always generates the correct code.
When the application entry point returns a Task
or Task<int>
, the compiler generates a new entry point that calls the entry point method declared in the application code. Assuming that this entry point is called $GeneratedMain
, the compiler generates the following code for these entry points:
-
static Task Main()
results in the compiler emitting the equivalent ofprivate static void $GeneratedMain() => Main().GetAwaiter().GetResult();
-
static Task Main(string[])
results in the compiler emitting the equivalent ofprivate static void $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
-
static Task<int> Main()
results in the compiler emitting the equivalent ofprivate static int $GeneratedMain() => Main().GetAwaiter().GetResult();
-
static Task<int> Main(string[])
results in the compiler emitting the equivalent ofprivate static int $GeneratedMain(string[] args) => Main(args).GetAwaiter().GetResult();
Note
If the examples used async
modifier on the Main
method, the compiler would generate the same code.
Command-Line Arguments
You can send arguments to the Main
method by defining the method in one of the following ways:
Main method code | Main signature |
---|---|
No return value, no use of await | static void Main(string[] args) |
Return value, no use of await | static int Main(string[] args) |
No return value, uses await | static async Task Main(string[] args) |
Return value, uses await | static async Task<int> Main(string[] args) |
If the arguments are not used, you can omit args
from the method signature for slightly simpler code:
Main method code | Main signature |
---|---|
No return value, no use of await | static void Main() |
Return value, no use of await | static int Main() |
No return value, uses await | static async Task Main() |
Return value, uses await | static async Task<int> Main() |
Note
You can also use Environment.CommandLine or Environment.GetCommandLineArgs to access the command-line arguments from any point in a console or Windows Forms application. To enable command-line arguments in the Main
method signature in a Windows Forms application, you must manually modify the signature of Main
. The code generated by the Windows Forms designer creates Main
without an input parameter.
The parameter of the Main
method is a String array that represents the command-line arguments. Usually you determine whether arguments exist by testing the Length
property, for example:
if (args.Length == 0) { System.Console.WriteLine("Please enter a numeric argument."); return 1; }
Tip
The args
array can't be null. So, it's safe to access the Length
property without null checking.
You can also convert the string arguments to numeric types by using the Convert class or the Parse
method. For example, the following statement converts the string
to a long
number by using the Parse method:
long num = Int64.Parse(args[0]);
It is also possible to use the C# type long
, which aliases Int64
:
long num = long.Parse(args[0]);
You can also use the Convert
class method ToInt64
to do the same thing:
long num = Convert.ToInt64(s);
For more information, see Parse and Convert.
The following example shows how to use command-line arguments in a console application. The application takes one argument at run time, converts the argument to an integer, and calculates the factorial of the number. If no arguments are supplied, the application issues a message that explains the correct usage of the program.
To compile and run the application from a command prompt, follow these steps:
-
Paste the following code into any text editor, and then save the file as a text file with the name Factorial.cs.
using System; 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) { // Test if input arguments were supplied. if (args.Length == 0) { Console.WriteLine("Please enter a numeric argument."); Console.WriteLine("Usage: Factorial <num>"); return 1; } // Try to convert the input arguments to numbers. This will throw // an exception if the argument is not a number. // num = int.Parse(args[0]); 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; } // Calculate factorial. long result = Functions.Factorial(num); // Print result. if (result == -1) Console.WriteLine("Input must be >= 0 and <= 20."); else Console.WriteLine($"The Factorial of {num} is {result}."); return 0; } } // If 3 is entered on command line, the // output reads: The factorial of 3 is 6.
-
From the Start screen or Start menu, open a Visual Studio Developer Command Prompt window, and then navigate to the folder that contains the file that you created.
-
Enter the following command to compile the application.
dotnet build
If your application has no compilation errors, an executable file that's named Factorial.exe is created.
-
Enter the following command to calculate the factorial of 3:
dotnet run -- 3
-
The command produces this output:
The factorial of 3 is 6.
C# language specification
For more information, see the C# Language Specification. The language specification is the definitive source for C# syntax and usage.
See also
- System.Environment
- How to display command line arguments
Feedback
Write a 'main' Method That Examines Its Command-line Arguments and
Source: https://docs.microsoft.com/en-us/dotnet/csharp/fundamentals/program-structure/main-command-line
0 Response to "Write a 'main' Method That Examines Its Command-line Arguments and"
Post a Comment