C#动态编译

控制台程序

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace CA.动态编译
{
    using Microsoft.CSharp;
    using System.CodeDom.Compiler;
    using System.Reflection;
    using System.IO;

    class Program
    {
        /*
         https://www.cnblogs.com/feigao/p/6197167.html
         https://www.cnblogs.com/duanjt/p/10875163.html
         https://www.cnblogs.com/hsiang/p/6505568.html
             */

       static MyClass my = new MyClass();

        static void Main(string[] args)
        {

        

            Console.WriteLine("1.编译");

            var m = Console.ReadKey();
            Console.WriteLine();

            if (m.Key == ConsoleKey.D1)
            {
                //动态编译
                string result = MyCode.GeneracCode(AppDomain.CurrentDomain.BaseDirectory + "\\Class2.txt");
                Console.WriteLine(result);

                Console.WriteLine("是否调用?(1.yes 2.no)");

                if (Console.ReadKey().Key == ConsoleKey.D1)
                {
                    Console.WriteLine("输入调用名称:");
                    string str = Console.ReadLine();
                    var arr = str.Split('.');
                    result = MyCode.LoadAssembly(result, arr[0], arr[1], arr[2]);
                    Console.WriteLine("调用结果:" + result);
                }

            }

            Console.ReadKey();

        }


       

    }
    class MyClass
    {
        public string Get(Action action) {
            action();
            return 1 + "3";
        }
    }


    public class MyCode
    {
        static string TestCode = @"
using System;

namespace Test {
    public class ClassA{
        public string f1(){
            return ""测试调用ok"";
        }

    }
}
";
        public static string GeneracCode(string path)
        {
            if (!File.Exists(path))
            {
                Console.WriteLine("文件路径不存在");
                return "文件路径不存在";
            }

            var codeTxt = File.ReadAllText(path);

            // 1.CSharpCodePrivoder
            CSharpCodeProvider ccp = new CSharpCodeProvider();
            // 2.ICodeComplier
            //ICodeCompiler cc = ccp.CreateCompiler();

            // 3.CompilerParameters
            CompilerParameters param = new CompilerParameters();
            param.ReferencedAssemblies.Add("System.dll");
            //param.ReferencedAssemblies.Add("System.Collections.Generic.dll");
            param.ReferencedAssemblies.Add("System.Linq.dll");
            //param.ReferencedAssemblies.Add("System.Text.dll");
            param.ReferencedAssemblies.Add("System.Threading.Tasks.dll");

            //自定义程序集
            param.ReferencedAssemblies.Add(@"D:\ys\Tool\pc\Console\ConsoleApp1\CA.动态编译\bin\Debug\Class1.dll");


            param.GenerateExecutable = false;
            param.GenerateInMemory = false;
            param.OutputAssembly = AppDomain.CurrentDomain.BaseDirectory + Path.GetFileName(path).Split('.')[0] + ".dll";
            //4.CompilerResult
            CompilerResults result = ccp.CompileAssemblyFromSource(param, codeTxt);

            if (result.Errors.HasErrors)
            {
                Console.WriteLine("编译错误:");
                foreach (CompilerError item in result.Errors)
                {
                    Console.WriteLine(item.ErrorText);
                }
            }

            else
            {
                Console.WriteLine("编译成功:" + result.PathToAssembly);
                // 通过反射,调用HelloWorld的实例
                //Assembly assembly = result.CompiledAssembly;

                //object instance = assembly.CreateInstance("命名空间.类名");
                //MethodInfo method = instance.GetType().GetMethod("函数名称");
                //method.Invoke(instance, null);
            }

            return result.PathToAssembly;
        }


        public static string LoadAssembly(string path, string nameSpace, string className, string methodName)
        {
            if (!File.Exists(path))
            {
                Console.WriteLine("程序集不存在");
                return "程序集不存在";
            }
            var dll = Assembly.LoadFile(path);

            //Module[] modules = dll.GetModules();//获取作为程序集一部分的所有模块信息
            string fullName = nameSpace + "." + className;
            Type type = dll.GetType(fullName);//获取程序集中定义的所有类型
            if (type == null)
            {
                Console.WriteLine("调用名称不存在");
                return "调用名称不存在";
            }

            object instance = dll.CreateInstance(fullName);
            if (instance == null)
            {
                Console.WriteLine("class 不存在");
                return "";
            }
            var method = instance.GetType().GetMethod(methodName);
            if (method == null)
            {
                Console.WriteLine("method 不存在");
                return "";
            }
            return method.Invoke(instance, null).ToString();

        }
    }
}

 

posted @ 2022-02-12 11:11  212的s  阅读(240)  评论(0编辑  收藏  举报