private async Task <object> HandleScriptErrors(Func <Task> doWork) { try { await doWork(); if (_scriptState?.Exception != null) { Console.WriteError(CSharpObjectFormatter.Instance.ToDisplayString(_scriptState.Exception)); } if (_scriptState?.ReturnValue != null) { _globals.Print(_scriptState.ReturnValue); } return(_scriptState.ReturnValue); } catch (CompilationErrorException e) { foreach (var diagnostic in e.Diagnostics) { Console.WriteError(diagnostic.ToString()); } } catch (Exception e) { Console.WriteError(CSharpObjectFormatter.Instance.ToDisplayString(e)); } return(null); }
public async Task <TReturn> Execute <TReturn>(string dllPath, IEnumerable <string> commandLineArgs) { var runtimeDeps = ScriptCompiler.RuntimeDependencyResolver.GetDependenciesForLibrary(dllPath); var runtimeDepsMap = ScriptCompiler.CreateScriptDependenciesMap(runtimeDeps); var assembly = Assembly.LoadFrom(dllPath); // this needs to be called prior to 'AppDomain.CurrentDomain.AssemblyResolve' event handler added try { //var p = runtimeDepsMap["System.Drawing.Common"].Path; //Console.WriteLine(p); //var a2 = Assembly.Load("System.Drawing.Common"); //var a3 = Assembly.LoadFrom(runtimeDepsMap["System.Drawing.Common"].Path); } catch (Exception ex) { Console.WriteLine(ex.Message); Console.WriteLine(ex.StackTrace); } AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => ResolveAssembly(args, runtimeDepsMap); var type = assembly.GetType("Submission#0"); var method = type.GetMethod("<Factory>", BindingFlags.Static | BindingFlags.Public); var globals = new CommandLineScriptGlobals(ScriptConsole.Out, CSharpObjectFormatter.Instance); foreach (var arg in commandLineArgs) { globals.Args.Add(arg); } var submissionStates = new object[2]; submissionStates[0] = globals; var resultTask = method.Invoke(null, new[] { submissionStates }) as Task <TReturn>; try { _ = await resultTask; } catch (System.Exception ex) { ScriptConsole.WriteError(ex.ToString()); throw new ScriptRuntimeException("Script execution resulted in an exception.", ex); } return(await resultTask); }
public virtual ScriptEmitResult Emit <TReturn, THost>(ScriptContext context) { try { var compilationContext = _scriptCompiler.CreateCompilationContext <TReturn, THost>(context); var compilation = compilationContext.Script.GetCompilation(); var peStream = new MemoryStream(); EmitOptions emitOptions = null; if (context.OptimizationLevel == Microsoft.CodeAnalysis.OptimizationLevel.Debug) { emitOptions = new EmitOptions() .WithDebugInformationFormat(DebugInformationFormat.Embedded); } var result = compilation.Emit(peStream, options: emitOptions); if (result.Success) { return(new ScriptEmitResult(peStream, compilation.DirectiveReferences, compilationContext.RuntimeDependencies)); } return(ScriptEmitResult.Error(result.Diagnostics)); } catch (CompilationErrorException e) { foreach (var diagnostic in e.Diagnostics) { _scriptConsole.WriteError(diagnostic.ToString()); } throw; } }
public async Task <TReturn> Execute <TReturn>(string dllPath, IEnumerable <string> commandLineArgs) { var runtimeDeps = ScriptCompiler.RuntimeDependencyResolver.GetDependenciesForLibrary(dllPath); var runtimeDepsMap = ScriptCompiler.CreateScriptDependenciesMap(runtimeDeps); var assembly = Assembly.LoadFrom(dllPath); // this needs to be called prior to 'AppDomain.CurrentDomain.AssemblyResolve' event handler added AppDomain.CurrentDomain.AssemblyResolve += (sender, args) => { var assemblyName = new AssemblyName(args.Name); var result = runtimeDepsMap.TryGetValue(assemblyName.Name, out RuntimeAssembly runtimeAssembly); if (!result) { throw new Exception($"Unable to locate assembly '{assemblyName.Name}: {assemblyName.Version}'"); } var loadedAssembly = Assembly.LoadFrom(runtimeAssembly.Path); return(loadedAssembly); }; var type = assembly.GetType("Submission#0"); var method = type.GetMethod("<Factory>", BindingFlags.Static | BindingFlags.Public); var globals = new CommandLineScriptGlobals(ScriptConsole.Out, CSharpObjectFormatter.Instance); foreach (var arg in commandLineArgs) { globals.Args.Add(arg); } var submissionStates = new object[2]; submissionStates[0] = globals; var resultTask = method.Invoke(null, new[] { submissionStates }) as Task <TReturn>; TReturn returnValue; try { returnValue = await resultTask; } catch (System.Exception ex) { ScriptConsole.WriteError(ex.ToString()); throw new ScriptRuntimeException("Script execution resulted in an exception.", ex); } return(await resultTask); }
private string CreateScriptAssembly <TReturn, THost>(ScriptContext context, string outputDirectory, string assemblyFileName) { try { var emitResult = _scriptEmitter.Emit <TReturn, THost>(context); if (!emitResult.Success) { throw new CompilationErrorException("One or more errors occurred when emitting the assembly", emitResult.Diagnostics); } var assemblyPath = Path.Combine(outputDirectory, $"{assemblyFileName}.dll"); using (var peFileStream = new FileStream(assemblyPath, FileMode.Create)) using (emitResult.PeStream) { emitResult.PeStream.WriteTo(peFileStream); } foreach (var reference in emitResult.DirectiveReferences) { if (reference.Display.EndsWith(".NuGet.dll")) { continue; } var referenceFileInfo = new FileInfo(reference.Display); var fullPathToReference = Path.GetFullPath(referenceFileInfo.FullName); var fullPathToNewAssembly = Path.GetFullPath(Path.Combine(outputDirectory, referenceFileInfo.Name)); if (!Equals(fullPathToReference, fullPathToNewAssembly)) { File.Copy(fullPathToReference, fullPathToNewAssembly, true); } } return(assemblyPath); } catch (CompilationErrorException ex) { _scriptConsole.WriteError(ex.Message); foreach (var diagnostic in ex.Diagnostics) { _scriptConsole.WriteError(diagnostic.ToString()); } throw; } }
public virtual Task <TReturn> Execute <TReturn, THost>(ScriptContext context, THost host) { try { var compilationContext = ScriptCompiler.CreateCompilationContext <TReturn, THost>(context); return(Execute(compilationContext, host)); } catch (CompilationErrorException e) { foreach (var diagnostic in e.Diagnostics) { ScriptConsole.WriteError(diagnostic.ToString()); } throw; } }
public virtual ScriptEmitResult Emit <TReturn, THost>(ScriptContext context, string assemblyName) { var compilationContext = _scriptCompiler.CreateCompilationContext <TReturn, THost>(context); foreach (var warning in compilationContext.Warnings) { _scriptConsole.WriteHighlighted(warning.ToString()); } if (compilationContext.Errors.Any()) { foreach (var diagnostic in compilationContext.Errors) { _scriptConsole.WriteError(diagnostic.ToString()); } throw new CompilationErrorException("Script compilation failed due to one or more errors.", compilationContext.Errors.ToImmutableArray()); } var compilation = compilationContext.Script.GetCompilation(); compilation = compilation.WithAssemblyName(assemblyName); var peStream = new MemoryStream(); EmitOptions emitOptions = null; if (context.OptimizationLevel == Microsoft.CodeAnalysis.OptimizationLevel.Debug) { emitOptions = new EmitOptions() .WithDebugInformationFormat(DebugInformationFormat.Embedded); } var result = compilation.Emit(peStream, options: emitOptions); if (result.Success) { return(new ScriptEmitResult(peStream, compilation.DirectiveReferences, compilationContext.RuntimeDependencies)); } return(ScriptEmitResult.Error(result.Diagnostics)); }
private string CreateScriptAssembly <TReturn, THost>(ScriptContext context, string outputDirectory, string assemblyFileName) { try { var emitResult = _scriptEmitter.Emit <TReturn, THost>(context); if (!emitResult.Success) { throw new CompilationErrorException("One or more errors occurred when emitting the assembly", emitResult.Diagnostics); } var assemblyPath = Path.Combine(outputDirectory, $"{assemblyFileName}.dll"); using (var peFileStream = new FileStream(assemblyPath, FileMode.Create)) using (emitResult.PeStream) { emitResult.PeStream.WriteTo(peFileStream); } foreach (var reference in emitResult.DirectiveReferences) { if (reference.Display.EndsWith(".NuGet.dll")) { continue; } var referenceFileInfo = new FileInfo(reference.Display); var fullPathToReference = Path.GetFullPath(referenceFileInfo.FullName); var fullPathToNewAssembly = Path.GetFullPath(Path.Combine(outputDirectory, referenceFileInfo.Name)); if (!Equals(fullPathToReference, fullPathToNewAssembly)) { File.Copy(fullPathToReference, fullPathToNewAssembly, true); } } /* The following is needed to make native assets work. * During a regular "dotnet publish" we find these assets in a "runtimes" folder. * We must copy these binaries up to the same folder as the script library so * that they can be found during execution. */ foreach (var runtimeDependency in emitResult.RuntimeDependencies) { if (!runtimeDependency.Name.Contains("microsoft.netcore", StringComparison.OrdinalIgnoreCase)) { foreach (var nativeAsset in runtimeDependency.NativeAssets) { File.Copy(nativeAsset, Path.Combine(outputDirectory, Path.GetFileName(nativeAsset)), true); } foreach (var runtimeAssembly in runtimeDependency.Assemblies) { File.Copy(runtimeAssembly.Path, Path.Combine(outputDirectory, Path.GetFileName(runtimeAssembly.Path)), true); var pathToRuntimeAssemblyFolder = Path.GetDirectoryName(runtimeAssembly.Path); var pdbFileName = $"{Path.GetFileNameWithoutExtension(runtimeAssembly.Path)}.pdb"; var pathToPdb = Path.Combine(pathToRuntimeAssemblyFolder, pdbFileName); if (File.Exists(pathToPdb)) { File.Copy(pathToPdb, Path.Combine(outputDirectory, Path.GetFileName(pathToPdb)), true); } } } } return(assemblyPath); } catch (CompilationErrorException ex) { _scriptConsole.WriteError(ex.Message); foreach (var diagnostic in ex.Diagnostics) { _scriptConsole.WriteError(diagnostic.ToString()); } throw; } }