Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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;
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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));
        }
Example #8
0
        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;
            }
        }