Getting started with C# scripting

Scripting in CSharp ain’t a big deal; it’s the same C# you use every day in your robust applications.

Structure of C# script file

C# scripting files are just plain-text files with the extension of .csx With #r "path of a DLL assembly" preprocessor-directives you can reference every DLL to the script Every C# code works inside the file, from implementing a class to using a namespace

Here is an example of simple CRX file:

Just a glimpse of the code, as you can see you can do everything!

But it’s csx file. How are you going to execute it? To write the script you need to have a specific tool. There are a couple of them such as:

Roslyn Mono CSI (if you install Visual Studio or Mono SDK you will have it on your OS)

(if you install Visual Studio or Mono SDK you will have it on your OS) dotnet-scripts global dotnet tool

global dotnet tool cs-scripts

I’m going to explain all of the tools I mentioned above then, in the end, we are going to compare them.

Running script with Mono/Roslyn CSI

I have installed Mono SDK on my OS, so I can access csi.exe directly via the command line! You can check if it’s on the path or not with where or whereis command.

C:\>where csi

C:\Program Files\Mono\bin\csi

C:\Program Files\Mono\bin\csi.bat

The first argument of CSI command is the csx file.

> csi sample-job1.csx Hello World!

Hello World, This file is created at 19/12/2019 11:40:37

Since it runs the file in interpreter mode, it takes one second. Now let’s reference some assembly to CSX file.

I downloaded Assembly dll of Newtonsoft.Json and put it next to my CSX file.

> csi sample-job2.csx {"Id":"5611f423-9819-4f02-887e-4d39e9a9b0b8","Name":"FooBar","Enabled":true}

I used JsonConvert.SerializeObject method to serialize a dummy object.

💡 If you just open csi app it will execute a repl in terminal and you can execute C# codes line by line.

C:\>csi

Microsoft (R) Visual C# Interactive Compiler version 3.3.1-beta4-19462-11 ()

Copyright (C) Microsoft Corporation. All rights reserved. Type "#help" for more information.

> var message= "Hello World";

> Console.WriteLine(message);

Hello World

>

How about referencing NuGet packages?

Unfortunately, CSI doesn’t support NuGet. So you have to download and put the DLL assembly next to your script manually. But as I’ve already mentioned, there are other tools that they support NuGet as well.

📒 Make sure you installed dotnet runtime/sdk on your platform.

▶ Dotnet-Script global tool

One of the best things about dotnet core CLI is its global tools. You can read about them here. In a nutshell, they are just a special NuGet package that contains a console application. A Global Tool can be installed on your machine on a default location that is included in the PATH environment variable or on a custom location.

This tool can be installed like this:

> dotnet tool install -g dotnet-script You can invoke the tool using the following command: dotnet-script

Tool 'dotnet-script' (version '0.50.1') was successfully installed.

dotnet-script tool has built-in NuGet support! So you can easily use this directive to reference any NuGet package your like.

#r “nuget: PackageId, version” // for e.g:

// #r “nuget: Newtonsoft.Json, 12.0.3”

Make sure you set the version because dotnet-script will cache the package for the next executions and this will make the script running more faster!

The first launch is a bit slow because it’s going to download the NuGet package with its dependencies!

> dotnet script sample-job3.csx {"Id":"5f14b3be-d634-414d-95e2-b015fda6d383","Name":"FooBar","Enabled":true}

The result is still the same, right?

One of the big advantages of dotnet-script is scaffolding which helps you create a folder for your script with launch settings for your beloved VSCode!

> dotnet-script init Creating VS Code launch configuration file

...'\path\.vscode\launch.json' [Created]

Creating OmniSharp configuration file

...'\path\omnisharp.json' [Created]

Creating default script file 'main.csx'

Creating 'main.csx'

...'\path\main.csx' [Created]

With this configuration, you can run and debug your code inside VSCode!

▶ Script-CS- makes it easy to write and execute C# with a simple text editor.

Compare to dotnet-script and CSI , Script-CS is a bit different. The only way to install it is via Chocolaty which is a windows package installer.

# install it with chocolaty cinst scriptcs

After installation, you have access to scripts command in CMD. By typing scripts in the cmd the scriptcs-repl will run, which let you enter C# codes line by line:

C:\>scriptcs

Moving directory '.cache' to '.scriptcs_cache'...

scriptcs (ctrl-c to exit or :help for help) > var message = "Hello World";

> Console.WriteLine(message);

Hello World

>

For installing NuGet packages, you can use -install argument. This should execute inside your script folder.

C:\>scriptcs -install Newtonsoft.Json Installing packages...

Installed: Newtonsoft.Json

Package installation succeeded.

Saving packages in scriptcs_packages.config...

Creating scriptcs_packages.config...

Added Newtonsoft.Json (v9.0.1, .NET 4.5) to scriptcs_packages.config

Successfully updated scriptcs_packages.config.

Writing code in ScriptCs is not really different from the others, here is an example:

And execute it like:

C:\>scriptcs sample-job2.csx {"Id":"e3a9d76e-d558-46d1-8d1a-b831c8013e16","Name":"FooBar","Enabled":true}

Referencing assemblies and the rest is the same as others with #r directive.

Debugging

It’s too bad the article does not mention how to debug such a script in an actual IDE when it’s needed…

— https://www.reddit.com/r/csharp/comments/ectt1v/hitchhikers_guide_to_the_c_scripting/fbe2l1g?utm_source=share&utm_medium=web2x

You cannot debug your scripts with CSI but Script-CS and Dotnet-Script offer the debugging, although Script-CS debugging is tricky requires Visual Studio and an extension that’s not 100% percent compatible with the latest Visual Studios. In this section, I only cover dotnet-script debugging.

Initialize a new script with dotnet-script scaffolder

> mkdir foo-bar > cd foo-bar > dotnet-script init foobar

Creating VS Code launch configuration file

...'\foo-bar\.vscode\launch.json' [Created]

Creating OmniSharp configuration file

...'\foo-bar\omnisharp.json' [Created]

Creating 'foobar'

...'\foo-bar\foobar.csx' [Created]

Install VSCode if you haven’t installed it already, then open the folder of the script like this:

code .

If this is the first time you are going to open any .cs or .csx file the VSCode is going to install C# Extension and Omnisharp it takes less than a minute. Now you can easily set breakpoints and Press F5 to run and debug your script!

Example of debugging in VSCode

Which one to use?

.-----------------.------.-------.----------------.--------.

| Name | Repl | Nuget | Cross-Platform | Debug |

:-----------------+------+-------+----------------+--------:

| Mono/Roslyn CSI | Yes | No | Yes | No |

:-----------------+------+-------+----------------+--------:

| Script-CS | Yes | Yes | No | Yes(1) |

:-----------------+------+-------+----------------+--------:

| Dotnet-Script | Yes | Yes | Yes | Yes |

'-----------------'------'-------'----------------'--------' 1. Script-CS supports debugging but it requies complete Visual Studio and it's not easy to do

In my humble opinion, dotnet-script is the best option, it has many other features such as compiling to exe but again it’s just my humble opinion, it’s always up to you and your needs and you need to see which tool solves your problems better.

References

These are a couple of references I used to get the background of C# scripting.