Compilation et réflection

Contenu du snippet

Un petit d exemple d utilisation du compilateur C# de .net.
J'en avais besoin pour une appli alors si ca peu vous faire gagner de temps...
Le code source est dans une chaine, il est compilé en mémoire.
Si la compilation réussi, on exécute le point d entrée avec paramètres, puis une méthode de test avec paramètres.
Si la compilation échoue, on affiche les erreurs.
Au passage, ca fait un petit exemple d utilisation de la réflexion en .Net

Source / Exemple :


using System;
using System.CodeDom.Compiler;
using System.Reflection;
using System.Text;

namespace cscomp
{
    static class Program
    {
        [STAThread]
        static void Main()
        {
            // Code source a compiler
            StringBuilder oSource = new StringBuilder();
            oSource
            .AppendLine("using System.Windows.Forms;")
            .AppendLine("namespace nsTest")
            .AppendLine("{")
            .AppendLine(" public static class Program")
            .AppendLine(" {")
            .AppendLine("  public static void Main()")
            .AppendLine("  {")
            .AppendLine("   MessageBox.Show(\"Hello !!\");")
            .AppendLine("  }")
            .AppendLine("  public static void Test(object args)")
            .AppendLine("  {")
            .AppendLine("   MessageBox.Show(\"Test :'\" + args.ToString() + \"'\");")
            .AppendLine("  }")
            .AppendLine(" }")
            .AppendLine("}");
            
            // Instanciation du compilateur et des ses paramètres
            CodeDomProvider oCodeProvider = new Microsoft.CSharp.CSharpCodeProvider();
            CompilerParameters oCompPrms = new CompilerParameters();

            // Définition des références
            oCompPrms.ReferencedAssemblies.Add("System.dll");
            oCompPrms.ReferencedAssemblies.Add("System.Windows.Forms.dll");
            
            // Paramètres non utilisé
            //oCompPrms.EmbeddedResources.Clear();
            //oCompPrms.LinkedResources.Clear();
            //oCompPrms.TempFiles.Clear(); 
            //oCompPrms.UserToken = new IntPtr(0);
            //oCompPrms.Win32Resource = "";
            //oCompPrms.OutputAssembly = "nsTest";
            //oCompPrms.CompilerOptions  = string.Empty;
            //oCompPrms.Evidence = null;
            
            //  Définition des paramètres de compilation
            oCompPrms.GenerateExecutable = true;
            oCompPrms.GenerateInMemory = true;
            oCompPrms.IncludeDebugInformation = false;
            oCompPrms.TreatWarningsAsErrors  = true;
            oCompPrms.MainClass = "nsTest.Program";
            oCompPrms.WarningLevel = 3;

            // Compilation du code
            CompilerResults oCompResults 
                = oCodeProvider.CompileAssemblyFromSource
                (oCompPrms, new string[] { oSource.ToString() });

            //  Si compilation réussie
            if (oCompResults.NativeCompilerReturnValue == 0)
            {
                // Lecture de l'assembly compilé
                Assembly oAssembly = oCompResults.CompiledAssembly;
    
                // Invocation du point d'entrée (Main)
                object oRunResult = oAssembly.EntryPoint.Invoke(null, null);
                
                // Invocation de la méthode test
                Type oType = oAssembly.GetType("nsTest.Program");
                MethodInfo oMethod = oType.GetMethod("Test", new Type[]{ typeof(object) });
                oMethod.Invoke(null, new object[] { "toto" });
            }

            // Si erreur de compilation
            else
            {
                // Affichage des erreurs
                foreach (CompilerError oCompError in oCompResults.Errors)
                {
                    string sCompError = string.Format
                    (
                        "{0} (l:{1},c:{2}) '{3}' ({4}):{5}",
                        (oCompError.IsWarning) ? "warning" : "error",
                        oCompError.Line.ToString(), oCompError.Column.ToString(),
                        oCompError.FileName,
                        oCompError.ErrorNumber, oCompError.ErrorText
                    );
                    System.Diagnostics.Debug.WriteLine(sCompError);
                }
            }

        }

    }

}

Conclusion :


Pour tester, créer un nouveau projet winform, et copier le code dans la classe program.

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.