using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting; using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows.Forms; namespace Tango.Scripting { /// /// Represents a C# scripting engine capable of executing C# scripts using the Roslyn engine. /// public class ScriptEngine { private CancellationTokenSource _cancaller; private OnExecuteParameters _onExecuteParameters; public List ReferencedAssemblies { get; private set; } /// /// Initializes a new instance of the class. /// /// The parameters. public ScriptEngine(OnExecuteParameters parameters) { _onExecuteParameters = parameters; ReferencedAssemblies = new List(); } /// /// Runs the specified code. /// /// The code. /// public async Task Run(String code) { var options = CreateOptions(); String methodParameters = CreateMethodParameters(); _cancaller = new CancellationTokenSource(); await CSharpScript.RunAsync( code + Environment.NewLine + Environment.NewLine + "await Task.Factory.StartNew(() => { OnExecute(" + methodParameters + "); });", options: options, globals: _onExecuteParameters, cancellationToken: _cancaller.Token); } public Task> Compile(String code) { return Task.Factory.StartNew>(() => { var options = CreateOptions(); String methodParameters = CreateMethodParameters(); _cancaller = new CancellationTokenSource(); var script = CSharpScript.Create( code + Environment.NewLine + Environment.NewLine + "await Task.Factory.StartNew(() => { OnExecute(" + methodParameters + "); });", options: options, globalsType: _onExecuteParameters.GetType()); var results = script.Compile(); return results.ToList().Select(x => new CompilerError() { Error = x.ToString() }).ToList(); }); } private String CreateMethodParameters() { return String.Join(", ", _onExecuteParameters.GetType().GetFields(BindingFlags.Public | BindingFlags.Instance).Select(x => x.Name)); } private ScriptOptions CreateOptions() { //My References. var options = ScriptOptions.Default; //My Assemblies. options = options.AddReferences(typeof(Form).Assembly.Location); options = options.AddReferences(typeof(Enumerable).Assembly.Location); options = options.AddReferences(typeof(ScriptEngine).Assembly.Location); foreach (var asm in ReferencedAssemblies) { options = options.AddReferences(asm.Assembly.Location); } //Imports. options = options.AddImports( "System", "System.Collections.Generic", "System.Linq", "System.Text", "System.Diagnostics", "System.Windows.Forms" ); return options; } /// /// Stops this instance. /// public void Stop() { _cancaller.Cancel(); } } }