using System.Collections.Generic; using System.CodeDom.Compiler; using Microsoft.CSharp; using System; using System.Reflection; using System.Diagnostics; namespace PingerService { public static class ScriptManager { private const string INCLUDE = "//#include"; private static string Self { get { return Process.GetCurrentProcess().MainModule.FileName; } } /// /// Contains a List of Compiler Errors that may occur on the "Load" Call, if it failed. /// public static CompilerErrorCollection LastErrors = null; /// /// Loads Source into Memory /// /// Source Code to load /// Loaded modules public static Module[] Load(string Content) { //Initialize Compiler string retValue = string.Empty; CodeDomProvider codeProvider = new CSharpCodeProvider(); CompilerParameters compilerParams = new CompilerParameters(); compilerParams.GenerateExecutable = false; compilerParams.GenerateInMemory = true; string[] Lines = Content.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); foreach (string Line in Lines) { //Check if Include Statement or Code if (Line.Trim().ToLower().StartsWith(INCLUDE)) { compilerParams.ReferencedAssemblies.Add(Line.Substring(INCLUDE.Length + 1)); } } //Compile CompilerResults results = codeProvider.CompileAssemblyFromSource(compilerParams, new string[] { Content }); //Check if Errors if (results.Errors.Count > 0) { LastErrors = results.Errors; return null; } return LoadAssembly(results.CompiledAssembly); } /// /// Loads an Assembly ang gets its Name /// /// Assembly to load /// Loaded modules private static Module[] LoadAssembly(Assembly a) { List Modules = new List(); foreach (Type type in a.GetTypes()) { if (type.IsPublic && !type.IsAbstract) { if (Module.IsModule(type)) { Modules.Add(new Module(type)); } else { Logger.Info("Not a module: {0}", type.Name); } } } return Modules.ToArray(); } /// /// Loads a compiled Script into Memory /// /// DLL File Name /// Loaded modules public static Module[] LoadLib(string Path) { return LoadAssembly(Assembly.LoadFile(System.IO.Path.GetFullPath(Path))); } /// /// Compiles source code into an assembly. /// Useful for larger files that take long to load. /// /// Source code /// Destination dll name public static void Compile(string Content, string Destination) { //Initialize Compiler string retValue = string.Empty; CodeDomProvider codeProvider = new CSharpCodeProvider(); CompilerParameters compilerParams = new CompilerParameters(); compilerParams.GenerateExecutable = false; compilerParams.GenerateInMemory = false; compilerParams.OutputAssembly = Destination; string[] Lines = Content.Split(new string[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); foreach (string Line in Lines) { //Check if Include Statement or Code if (Line.Trim().ToLower().StartsWith(INCLUDE)) { compilerParams.ReferencedAssemblies.Add(Line.Substring(INCLUDE.Length + 1)); } } //Compile CompilerResults results = codeProvider.CompileAssemblyFromSource(compilerParams, new string[] { Content }); //Check if Errors if (results.Errors.Count > 0) { LastErrors = results.Errors; } } } }