.Net – Compile C# at runtime|.Net compiler du C# a l’execution
I do not remember where I found this code, but it is very interesting :
you can compile C# in an assembly and then use it as you like.
Voici du code qui permet de compiler du C# a l’execution. L’assembly est gardé en mémoire (mais pourrait etre mis dans un fichier) et est directement utilisable.
What I do
I compile C# but in my code I am using it directly in a method (a constructor). In the real situation I used it in another way, but it was in my job so I cannot explain here what I did.
Anyway, everyone can use it as he likes.
Ce que je fais
Je compile du C# et j’instancie un objet. En réalité je l’utilise pour autre chose (mais c’est dans mon travail alors je le garde pour moi ^^).
Mais chacun peut en faire ce qu’il veut!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Reflection;
using System.CodeDom;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Collections;
using System.Text;
/// <summary>
/// CSharpCompiler
/// </summary>
public class CSharpCompiler
{
// Compilation errors
private StringBuilder errors = new StringBuilder();
public string Errors
{
get
{
return "Error in the compilation :\n" + errors.ToString();
}
}
public CSharpCompiler(){}
private string AddClass(string source)
{
return "using System;" +
"using System.Collections.Generic;" +
"using System.Text;" +
"public class MySpecialClass" +
"{" +
"public MySpecialClass()" +
"{" +
source +
"}" +
"}";
}
public Object Run(string source)
{
// Clean error
errors.Length = 0;
// Compile
Assembly assembly = CreateAssembly(AddClass(source));
if (assembly == null) return null;
Object obj = assembly.CreateInstance("MySpecialClass");
return obj;
}
private Assembly CreateAssembly(string sourceInClass)
{
//On crée une class pour compiler le C#
CodeDomProvider codeProvider = new CSharpCodeProvider();
// On devait precedement crée un compilateur
///Depreciated ICodeCompiler compiler = codeProvider.CreateCompiler();
//parametres du compilateur
CompilerParameters compilerParams = new CompilerParameters();
compilerParams.CompilerOptions = "/target:library"; // you can add /optimize
compilerParams.GenerateExecutable = false;
compilerParams.GenerateInMemory = true;
compilerParams.IncludeDebugInformation = false;
//references
compilerParams.ReferencedAssemblies.Add("mscorlib.dll");
compilerParams.ReferencedAssemblies.Add("System.dll");
compilerParams.ReferencedAssemblies.Add("System.Data.dll");
compilerParams.ReferencedAssemblies.Add("System.Xml.dll");
compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
// On compile
// depreciated compiler.CompileAssemblyFromSource(
CompilerResults results = codeProvider.CompileAssemblyFromSource(
compilerParams,
sourceInClass);
// On garde les erreurs
if (results.Errors.Count > 0)
{
foreach (CompilerError error in results.Errors)
{
errors.AppendLine("Error : " + error.ErrorText);
}
return null;
}
// recupere l'assembly
Assembly generatedAssembly = results.CompiledAssembly;
// retourne l'assembly
return generatedAssembly;
}
//
// Imagine we want to call Main function, so use this method.
//
// invoke the entry method
// this method code is mainly from jconwell,
// see http://www.codeproject.com/dotnet/DotNetScript.asp
/*
private void CallEntry(Assembly assembly, string entryPoint)
{
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;
}
}
errors.AppendLine("Impossible d'acceder au point d'entre : " + entryPoint);
}
catch (Exception ex)
{
errors.AppendLine("Erreur : " + ex.Message);
}
}
*/
}
You can imagine what you want and Wow I really like this powerful capacity in .Net
But here is how is use it :
Vous pouvez imaginer comme c’est puissant et toutes les possibilités d’utiliser du .Net pendant l’execution.
Voici la fin :
static void Main(string[] args)
{
CSharpCompiler csc = new CSharpCompiler();
// The code to compile
Object p = csc.Run("Console.WriteLine(\"Hello\");");
if (p == null) Console.WriteLine(csc.Errors);
}
Subscribe to the RSS feed and have all new posts delivered straight to you.
