Run C# scripts from the .NET CLI.
What do I need to install?
Nothing - everything is self contained from the project.json level. Just make sure you have .NET Core installed and dotnet available in your PATH.
1> Create a project.json file with your dependencies and reference Dotnet.Script as a tool:
{
"dependencies": {
"Automapper": "5.1.1",
"Newtonsoft.Json": "9.0.1"
},
"frameworks": {
"netcoreapp1.0": {
}
},
"tools": {
"Dotnet.Script": {
"version": "*",
"imports": [
"portable-net45+win8",
"dnxcore50"
]
}
}
}
In the above case we will pull in Automapper and Newtonsoft.Json from nuget into our script.
2> Run dotnet restore
3> Now, create a C# script beside the project.json. You can use any types from the packages you listed in your dependencies. You can also use anything that is part of Microsoft.NETCore.App. Your script will essentially be a netcoreapp1.0 app.
For example:
using Newtonsoft.Json;
using AutoMapper;
Console.WriteLine("hello!");
var test = new { hi = "i'm json!" };
Console.WriteLine(JsonConvert.SerializeObject(test));
Console.WriteLine(typeof(MapperConfiguration));4> You can now execute your script using dotnet script foo.csx.
CSX script could also be located elsewhere and referenced by absolute path - what's important is that the
project.jsonwith its dependencies is located next to the script file, and that restore was run beforehand.
This should produce the following output:
λ dotnet script foo.csx
hello!
{"hi":"i'm json!"}
AutoMapper.MapperConfigurationdotnet-script supports debugging C# scripts. In order to do that we'll need to be able to invoke dotnet-script.dll directly - rather than via dotnet CLI.
Normally, the nuget package with the dotnet-script.dll will be globally located on your machine (on Windows) in C:\Users\{user}\.nuget\packages\ folder let's refer to that location as <NUGET_ROOT>.
To debug a script using Visual Studio Code, create a folder .vscode next to your script and put the following launch.json file inside (make sure to replace <NUGET_ROOT> with your global nuget packages path, ensure that the path to dotnet.exe is correct and that dotnet-script version matches the one you have got installed!).
{
"version": "0.2.0",
"configurations": [
{
"name": ".NET Script Debug",
"type": "coreclr",
"request": "launch",
"program": "C:\\Program Files\\dotnet\\dotnet.exe", // path to your dotnet.exe installation
"args": ["exec", "--additionalprobingpath", "<NUGET_ROOT>", "--depsfile", "<NUGET_ROOT>\\Dotnet.Script\\0.3.1-beta\\lib\\netcoreapp1.0\\dotnet-script.deps.json", "<NUGET_ROOT>\\Dotnet.Script\\0.3.1-beta\\lib\\netcoreapp1.0\\dotnet-script.dll", "${workspaceRoot}\\foo.csx","-d"],
"cwd": "${workspaceRoot}",
"externalConsole": false,
"stopAtEntry": true,
"internalConsoleOptions": "openOnSessionStart"
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach",
"processId": "${command.pickProcess}"
}
]
}
You can now set breakpoints inside your CSX file and launch the debugger using F5.
dotnet script is compatible with the official dotnet CLI file watcher tool. To use the file watcher (re-run the script automatically upon each change) you will need to add the following Microsoft.DotNet.Watcher.Tools reference to your project.json:
"tools": {
"Dotnet.Script": {
"version": "*",
"imports": [
"portable-net45+win8",
"dnxcore50"
]
},
"Microsoft.DotNet.Watcher.Tools": {
"version": "1.0.0-preview2-final"
}
}Additionally, you need to instruct the watcher to monitor csx files. This is done via buildOptions in project.json:
"buildOptions": {
"compile": "**/*.csx"
},After restoring Microsoft.DotNet.Watcher.Tools, you can now run your script as follows:
dotnet watch script foo.csx
This will run foo.csx and watch for changes in it, automatically re-running it any time you make any changes.
You can also reference a script from a script - this is achieved via the #load directive.
Imagine having the following 2 CSX files side by side - bar.csx and foo.csx:
Console.WriteLine("Hello from bar.csx");#load "bar.csx"
Console.WriteLine("Hello from foo.csx");Running dotnet script foo.csx will produce:
Hello from bar.csx
Hello from foo.csxEven better, Dotnet.Script supports loading CSX references over HTTP too. You could now modify the foo.csx accordingly:
#load "https://gist.githubusercontent.com/filipw/9a79bb00e4905dfb1f48757a3ff12314/raw/adbfe5fade49c1b35e871c49491e17e6675dd43c/foo.csx"
#load "bar.csx"
Console.WriteLine("Hello from foo.csx");In this case, the first dependency is loaded as string and parsed from an HTTP source - in this case a gist I set up beforehand.
Running dotnet script foo.csx now, will produce:
Hello from a gist
Hello from bar.csx
Hello from foo.csxAll arguments after -- are passed to the script in the following way:
dotnet script foo.csx -- arg1 arg2 arg3
Then you can access the arguments in the script context using the global Args collection:
foreach (var arg in Args)
{
Console.WriteLine(arg);
}
All arguments before -- are processed by dotnet script. For example, the following command-line
dotnet script -d foo.csx -- -d
will pass the -d before -- to dotnet script and enable the debug mode whereas the -d after -- is passed to script for its own interpretation of the argument.
Due to this .NET CLI bug in order to debug the cloned solution, comment out the buildOptions > outputName property in project.json.
Special thanks to Bernhard Richter for his help with .NET Core debugging.

