internal static String CompileSource(string SourceCode, bool inmemory, bool isExe, string compoptions) { // What assembly we are in, do not include on load; Assembly currentAssem = Assembly.GetExecutingAssembly(); // We want to bring in Micrsosoft.CSharp dll for scripts that use dynamic constructs. // While the dll is CSharpUtil.LoadCSCompilNamespace(); String[] referencedAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.FullName.StartsWith("mscorlib", StringComparison.InvariantCultureIgnoreCase)) .Where(a => !a.FullName.StartsWith(currentAssem.FullName, StringComparison.InvariantCultureIgnoreCase)) .Where(a => !a.IsDynamic) .Select(a => a.Location) .ToArray(); AssemblyUtil.showAssembliesInDomain(AppDomain.CurrentDomain); Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider( new Dictionary <string, string>() { { "CompilerVersion", "v4.0" } }); CompilerParameters parameters = new CompilerParameters( referencedAssemblies); if (inmemory) { parameters.GenerateInMemory = true; } else { parameters.GenerateInMemory = false; } if (isExe) { parameters.GenerateExecutable = true; } else { parameters.GenerateExecutable = false; } parameters.TempFiles = new TempFileCollection(Path.GetTempPath(), true); parameters.CompilerOptions = compoptions; String aPathName = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(Path.GetTempFileName()).Replace(".tmp", ".dll")); parameters.OutputAssembly = aPathName; CompilerResults cr = csc.CompileAssemblyFromSource(parameters, SourceCode); if (cr.Errors.HasErrors) { foreach (String output in cr.Output) { Console.WriteLine(output); } return(String.Empty); } return(aPathName); }
/// <summary> /// Compile and run CSharp code snippets /// </summary> /// <param name="SnippetDirectives"></param> /// <param name="SnippetCode"></param> /// <returns></returns> internal static bool CompileRunSnippet(string SnippetDirectives, string SnippetCode) { using (var context = AppDomainContext.Create()) { // What assembly we are in, do not include on load; Assembly currentAssem = Assembly.GetExecutingAssembly(); String[] referencedAssemblies = AppDomain.CurrentDomain.GetAssemblies() .Where(a => !a.FullName.StartsWith(currentAssem.FullName, StringComparison.InvariantCultureIgnoreCase)) .Where(a => !a.IsDynamic) //is necessary because a dynamic assembly will throw and exception when calling a.Location .Select(a => a.Location) .ToArray(); // We want to bring in Micrsosoft.CSharp dll for scripts that use dynamic constructs. // While the dll is CSharpUtil.LoadCSCompilNamespace(); //String[] referencedAssemblies = AppDomain.CurrentDomain.GetAssemblies() // .Where( a => !a.IsDynamic) // .Select(a => a.Location).ToArray(); if (!ConfigUtil.DEBUG) { foreach (String ra in referencedAssemblies) { Console.WriteLine("Including assembly: {0}", ra); } } // A Wrapper around the snippet, with proper object disposal #region ScriptText String SnippetPreamble = @" namespace Dynamic { public class DynamicCompile: System.IDisposable{ private bool disposed = false; public DynamicCompile(){ // Console.WriteLine(""=== Dynamic CScript === ""); } public void GetResults(){ try { "; String SnippetPostAmble = @" }catch(Exception e){ Console.WriteLine(""Exception : {0} "", e); } } //Implement IDisposable. public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } protected virtual void Dispose(bool disposing) { if (!disposed) { if (disposing) { // Free other state (managed objects). } // Free your own state (unmanaged objects). // Console.WriteLine(""=== End Dynamic CScript === ""); disposed = true; } } // Use C# destructor syntax for finalization code. ~DynamicCompile(){ // Simply call Dispose(false). Dispose (false); } } }"; String SourceCode = SnippetDirectives + SnippetPreamble + SnippetCode + SnippetPostAmble; #endregion ScriptText Microsoft.CSharp.CSharpCodeProvider csc = new Microsoft.CSharp.CSharpCodeProvider( new Dictionary <string, string>() { { "CompilerVersion", "v4.0" } }); CompilerParameters parameters = new CompilerParameters( referencedAssemblies); parameters.GenerateInMemory = true; parameters.GenerateExecutable = false; parameters.TempFiles = new TempFileCollection(Path.GetTempPath(), true); parameters.CompilerOptions += "/nologo /unsafe"; String aPathName = Path.Combine(Environment.CurrentDirectory, Path.GetFileName(Path.GetTempFileName()).Replace(".tmp", ".dll")); parameters.OutputAssembly = aPathName; CompilerResults cr = csc.CompileAssemblyFromSource(parameters, SourceCode); if (cr.Errors.HasErrors) { foreach (String output in cr.Output) { Console.WriteLine(output); } return(false); } var type = cr.CompiledAssembly.GetType("Dynamic.DynamicCompile"); FileInfo fi = new FileInfo(aPathName); File.Delete(aPathName); object[] constructorArgs = new object[] { }; dynamic instance = Activator.CreateInstance(type, constructorArgs); Console.WriteLine("\n--- Result ---"); instance.GetResults(); // Dispose of instances. Avoiding memory leaks (e.g. for rapid fire of calls in a loop). instance.Dispose(); //GC.Collect(); //GC.WaitForPendingFinalizers(); } return(true); }