namespace ElementalGame { using System; using System.Collections.Generic; using System.Text; using System.IO; using System.CodeDom; using System.CodeDom.Compiler; using System.Reflection; using Microsoft.VisualC; public class Compiler { CodeDomProvider provider; // CSharp and VB CppCodeProvider cppProvider; // C++ ICodeCompiler compiler; CompilerResults results; AppDomain appDomain; Assembly assembly; public enum Language { CPP, CSHARP, VB, JSHARP, NONE }; public Language language = Compiler.Language.NONE; // Create a dedicated compiler for chosen language public Compiler(Language language) { // To hardcode directory path =================================================== //AppDomainSetup domaininfo = new AppDomainSetup(); //domaininfo.ApplicationBase = "f:\\work\\development\\latest"; //domaininfo.ConfigurationFile = "f:\\work\\development\\latest\\appdomain5.exe.config"; //appDomain = AppDomain.CreateDomain("MyDomain", null, domaininfo); // ============================================================================== //Create an AppDomain to compile and execute the code //This enables us to cancel the execution if needed appDomain = AppDomain.CreateDomain("MyDomain"); // Write application domain information to the console. Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName); Console.WriteLine("child domain: " + appDomain.FriendlyName); Console.WriteLine("App base is: " + appDomain.SetupInformation.ApplicationBase); switch (language) { case Compiler.Language.CPP: cppProvider = new CppCodeProvider(); break; case Compiler.Language.CSHARP: provider = new Microsoft.CSharp.CSharpCodeProvider(); break; case Compiler.Language.VB: provider = new Microsoft.VisualBasic.VBCodeProvider(); break; case Compiler.Language.JSHARP: provider = (CodeDomProvider)Activator.CreateInstance( "Microsoft.JScript", "Microsoft.JScript.JScriptCodeProvider").Unwrap(); break; } } // Compile from file public void CompileAssemblyFromSource(string file) { //CodeManager manager = (CodeManager)appDomain.CreateInstanceFromAndUnwrap( // typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly.Location, typeof(CodeManager).FullName); // Set up compiler params CompilerParameters compilerparams = new CompilerParameters(); compilerparams.GenerateInMemory = true; compilerparams.GenerateExecutable = true; compilerparams.IncludeDebugInformation = true; compilerparams.ReferencedAssemblies.Add("System.Windows.Forms.dll"); compilerparams.ReferencedAssemblies.Add("System.dll"); // Get compilation results if (language == Compiler.Language.CPP) { results = cppProvider.CompileAssemblyFromFile(compilerparams, file); } else { results = provider.CompileAssemblyFromFile(compilerparams, file); } // DEBUG DisplayCompilerResults(results); } // Compile from file public void CompileAssemblyFromFile(string source) { //CodeManager manager = (CodeManager)executionDomain.CreateInstanceFromAndUnwrap( // typeof(Microsoft.CSharp.CSharpCodeProvider).Assembly.Location, typeof(CodeManager).FullName); // Set up compiler params CompilerParameters compilerparams = new CompilerParameters(); compilerparams.GenerateInMemory = true; compilerparams.GenerateExecutable = true; compilerparams.IncludeDebugInformation = true; compilerparams.ReferencedAssemblies.Add("System.Windows.Forms.dll"); compilerparams.ReferencedAssemblies.Add("System.dll"); // Get compilation results if (language == Compiler.Language.CPP) { results = cppProvider.CompileAssemblyFromSource(compilerparams, source); } else { results = provider.CompileAssemblyFromSource(compilerparams, source); } // DEBUG DisplayCompilerResults(results); } // Displays information from a CompilerResults. public static void DisplayCompilerResults(CompilerResults results) {// http://msdn2.microsoft.com/en-us/library/system.codedom.compiler.compilerresults.aspx // If errors occurred during compilation, output the compiler output and errors. if (results.Errors.Count > 0) { for (int i = 0; i < results.Output.Count; i++) Console.WriteLine(results.Output[i]); for (int i = 0; i < results.Errors.Count; i++) Console.WriteLine(i.ToString() + ": " + results.Errors[i].ToString()); } else { // Display information about the compiler's exit code and the generated assembly. Console.WriteLine("Compiler returned with result code: " + results.NativeCompilerReturnValue.ToString()); Console.WriteLine("Generated assembly name: " + results.CompiledAssembly.FullName); if (results.PathToAssembly == null) Console.WriteLine("The assembly has been generated in memory."); else Console.WriteLine("Path to assembly: " + results.PathToAssembly); // Display temporary files information. if (!results.TempFiles.KeepFiles) Console.WriteLine("Temporary build files were deleted."); else { Console.WriteLine("Temporary build files were not deleted."); // Display a list of the temporary build files //IEnumerator enu = results.TempFiles.GetEnumerator(); //for (int i = 0; enu.MoveNext(); i++) // Console.WriteLine("TempFile " + i.ToString() + ": " + (string)enu.Current); } } } public void LoadAssembly(string assemblyName) { // Use the file name to load the assembly into the current // application domain. appDomain.Load(new AssemblyName(assemblyName)); } // eg Type = "Example" (class name), Method = "MethodA" (method name) public void ExecuteAssemblyMethod(string type, string method, object[] parameters) { // Get the type to use. Type myType = assembly.GetType(type); // Create an instance. Object obj = Activator.CreateInstance(myType); // Get the method to call. MethodInfo mymethod = myType.GetMethod(method); // Execute the method. mymethod.Invoke(obj, parameters); // Binded excecution // mymethod.Invoke(obj, BindingFlags.Static, null, parameters, null); } // invoke the entry method public void ExecuteAssemblyMethod(Assembly assembly, string entryPoint) { // see http://www.codeproject.com/dotnet/DotNetScript.asp try { //Use reflection to call the static Main function Module[] mods = assembly.GetModules(false); Type[] types = mods[0].GetTypes(); foreach (Type type in types) { MethodInfo mi = type.GetMethod(entryPoint, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static); if (mi != null) if( mi.GetParameters().Length == 1 ) if( mi.GetParameters()[0].ParameterType.IsArray ) { string [] par = new string[1]; // if Main has string [] arguments mi.Invoke(null, par); } else mi.Invoke(null, null); return; } } catch (Exception ex) { } } } }