In learning C# I have resisted using Windows, continuing to use Linux (Ubuntu) for all my software development, which in this case is no doubt holding me back in ways I do not yet even realise.
For my C# coding I am using JetBrains Rider IDE.
Having already installed the Dot Net Core runtime and Mono, I am able to Run and Debug my C# code direct from the IDE:
When I click these buttons, things happen – a log output very briefly pops up – but I haven’t had to worry about what is happening to make my code actually build and run behind the scenes.
That is, until I wanted to pass in some arguments to my command line based app. At this point I decided it was time to investigate just how to run a C# project from the Linux command line.
Pre-requisites
To run a C# project from the command line on a Linux system, you will need to have the .NET Core runtime installed on your machine. You can download and install the .NET Core runtime from the following link:
https://dotnet.microsoft.com/download/dotnet-core
Once you have the .NET Core runtime installed, you can use the dotnet
command to run a C# project from the command line.
Run a C# Project From Linux Command Line
To run a C# project, navigate to the directory containing the project file (for example, *.csproj
) and enter the following command:
dotnet run
Code language: Shell Session (shell)
This will build and run the project.
Alternatively, you can build the project and generate an executable file by entering the following command:
dotnet build
Code language: Shell Session (shell)
This will build the project and generate an executable file (for example, *.dll
) in the bin
directory. You can then run the executable file by entering the following command:
dotnet path/to/executable.dll
Code language: Shell Session (shell)
Replace path/to/executable.dll
with the path to the executable file generated by the dotnet build
command.
Note that you may need to make the executable file executable by changing its permissions with the chmod
command before you can run it.
Example Output
Taking my LinkVisitor project as an example, my first assumption was that I should run the C# code from the directory that Rider has created.
For example, when I click the Run button, I see the following path in the Rider integrated terminal:
/home/chris/RiderProjects/LinkVisitorCSharp/LinkVisitorCSharp/bin/Debug/net6.0/LinkVisitorCSharp
Code language: Shell Session (shell)
I can run that path directly, presumably because dotnet
is on my Path
:
echo $PATH
/home/chris/.sdkman/candidates/java/current/bin:/home/chris/.nvm/versions/node/v18.11.0/bin:/home/chris/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/snap/bin:<strong>/home/chris/.dotnet/tools</strong>:/usr/local/go/bin:/home/chris/.local/share/JetBrains/Toolbox/scripts
Code language: Shell Session (shell)
When I browse to that bin/Debug/net6.0/LinkVisitorCSharp
directory path, I have the following contents:
➜ net6.0 ls -la
total 120
drwxrwxr-x 3 chris chris 4096 Dec 17 20:29 .
drwxrwxr-x 3 chris chris 4096 Dec 17 20:29 ..
-rwxr-xr-x 1 chris chris 77208 Jan 2 10:08 LinkVisitorCSharp
-rw-rw-r-- 1 chris chris 421 Dec 29 20:30 LinkVisitorCSharp.deps.json
-rw-rw-r-- 1 chris chris 11776 Jan 2 10:08 LinkVisitorCSharp.dll
-rw-rw-r-- 1 chris chris 11916 Jan 2 10:08 LinkVisitorCSharp.pdb
-rw-rw-r-- 1 chris chris 139 Dec 23 20:57 LinkVisitorCSharp.runtimeconfig.json
drwxrwxr-x 2 chris chris 4096 Dec 17 20:29 ref
Code language: Shell Session (shell)
This was where I got confused.
➜ net6.0 dotnet run
Couldn't find a project to run. Ensure a project exists in /home/chris/RiderProjects/LinkVisitorCSharp/LinkVisitorCSharp/bin/Debug/net6.0, or pass the path to the project using --project.
➜ net6.0 dotnet build
Microsoft (R) Build Engine version 17.0.1+b177f8fa7 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
MSBUILD : error MSB1003: Specify a project or solution file. The current working directory does not contain a project or solution file.
Code language: Shell Session (shell)
My mistake was being in the wrong directory. I needed to go up three directories to the project root:
➜ net6.0 cd ..
➜ Debug cd ..
➜ bin cd ..
➜ LinkVisitorCSharp pwd
/home/chris/RiderProjects/LinkVisitorCSharp/LinkVisitorCSharp
➜ LinkVisitorCSharp ls -la
total 40
drwxrwxr-x 4 chris chris 4096 Jan 2 10:08 .
drwxrwxr-x 5 chris chris 4096 Dec 23 20:32 ..
drwxrwxr-x 3 chris chris 4096 Dec 17 20:29 bin
-rw-rw-r-- 1 chris chris 236 Dec 28 12:59 HttpClientFactory.cs
-rw-rw-r-- 1 chris chris 1965 Jan 2 09:33 LinkVisitor.cs
-rw-rw-r-- 1 chris chris 259 Dec 29 20:26 LinkVisitorCSharp.csproj
drwxrwxr-x 3 chris chris 4096 Dec 23 20:44 obj
-rw-rw-r-- 1 chris chris 1227 Jan 2 10:08 Program.cs
-rw-rw-r-- 1 chris chris 265 Dec 29 20:34 Validator.cs
-rw-rw-r-- 1 chris chris 981 Dec 23 21:15 VisitedUrl.cs
Code language: Shell Session (shell)
From here, the project does build and run:
➜ LinkVisitorCSharp dotnet build
Microsoft (R) Build Engine version 17.0.1+b177f8fa7 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.
Determining projects to restore...
All projects are up-to-date for restore.
LinkVisitorCSharp -> /home/chris/RiderProjects/LinkVisitorCSharp/LinkVisitorCSharp/bin/Debug/net6.0/LinkVisitorCSharp.dll
Build succeeded.
0 Warning(s)
0 Error(s)
Time Elapsed 00:00:00.61
Code language: Shell Session (shell)
And:
That output is very specific to my project.
The key thing is that I can easily pass in command line arguments simply by adding extra information to my command line call:
dotnet run https://aka.ms/new-console-template
//
dotnet run anything goes here
Code language: Shell Session (shell)