I'm working on a project targeting netcoreapp1.0
on OSX, and I'm setting up a script using Roslyn like this:
var scriptText = File.ReadAllText(args[0]);
var scriptOptions = ScriptOptions.Default
.WithReferences(
typeof(System.Object).GetTypeInfo().Assembly
);
var script = CSharpScript.Create(scriptText, scriptOptions, typeof(Globals));
var scriptArgs = new string[args.Length-1];
Array.Copy(args, 1, scriptArgs, 0, args.Length-1);
script.RunAsync(new Globals
{
Args = scriptArgs
})
.GetAwaiter().GetResult();
Where Globals
is:
public class Globals
{
public string[] Args { get; set; }
}
When I try to run a script that looks like this:
using System;
Console.WriteLine("Args[0]: {0}", Args[0]);
The program terminates with this exception:
$ dotnet run test.csx
Project BitThicket.DotNet.ScriptTool (.NETCoreApp,Version=v1.0) was previously compiled. Skipping compilation.
Script error: Microsoft.CodeAnalysis.Scripting.CompilationErrorException: (7,9): error CS1501: No overload for method 'WriteLine' takes 2 arguments
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.ThrowIfAnyCompilationErrors(DiagnosticBag diagnostics, DiagnosticFormatter formatter)
at Microsoft.CodeAnalysis.Scripting.ScriptBuilder.CreateExecutor[T](ScriptCompiler compiler, Compilation compilation, CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.GetExecutor(CancellationToken cancellationToken)
at Microsoft.CodeAnalysis.Scripting.Script`1.RunAsync(Object globals, Func`2 catchException, CancellationToken cancellationToken)
at BitThicket.DotNet.ScriptTool.Program.Main(String[] args) in /Users/ben/proj/bt/dotnet-scriptcs/src/BitThicket.DotNet.ScriptTool/Program.cs:line 63
Obviously Console
does, in fact, have an overload that takes 2 methods. I looked at the CoreFx sources briefly to see if there were any odd type-forwarding or extension method tricks being used that might need additional care in the script setup, but I didn't see anything unusual there (maybe I missed something).
Why would the Roslyn ScriptBuilder
then complain about this?
In .NET Core, the Console
class is in the System.Console
assembly, so you'll need to add it to the script's references:
var scriptOptions = ScriptOptions.Default
.WithReferences(
typeof(System.Object).GetTypeInfo().Assembly,
typeof(System.Console).GetTypeInfo().Assembly
);
If you check the assembly location of Object
, you'll see it's System.Private.CoreLib.ni.dll
. Using ILSpy, we can see this assembly only contains a basic Console
implementation, with the methods Write(string s)
, WriteLine(string s)
and WriteLine()
. Whereas the System.Console
assembly contains the full implementation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With