C# 动态编译并调用执行。

 

编译+执行代码如下

 

//using System;

//namespace DynamicCode
//{
//    class Program
//    {
//        static void Main(string[] args)
//        {
//            Console.WriteLine("Hello World!");
//        }
//    }
//}

using System;
using System.Collections.Generic;
//using System.Windows.Forms;
using System.Threading.Tasks;

using System.IO;
using System.Reflection;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using static System.Net.Mime.MediaTypeNames;

namespace Excuter
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            //Application.EnableVisualStyles();
            //Application.SetCompatibleTextRenderingDefault(false);
            //Application.Run(new Form1());

            if (args == null || args.Length == 0) args = new string[] { @"D:\coding\JahwaPLM\test.cs" };
            if (args != null && args.Length > 0)
            {
                // 其他参数作为执行参数
                string[] Arg = null;
                if (args.Length > 1)
                {
                    Arg = new string[args.Length - 1];
                    for (int i = 1; i < args.Length; i++)
                    {
                        Arg[i - 1] = args[i];
                    }
                }

                // 第一个参数作为源码或源码文件
                if (File.Exists(args[0])) Excute.RunFileFirst(args[0], Arg);
                else Excute.RunSourceCodeFirst(args[0], Arg);
            }

        }
    }

    /// <summary>
    /// 动态编译执行
    /// </summary>
    public class Excute
    {

        #region 动态编译源码并执行

        /// <summary>
        /// 解析并编译执行源码文件sourceFile,第一个类的首个公用或静态方法
        /// </summary>
        public static object RunFileFirst(string sourceFile, object[] args = null)
        {
            try
            {
                string sourceCode = fileToString(sourceFile);
                return RunSourceCodeFirst(sourceCode, args);
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }

        /// <summary>
        /// 解析并编译执行sourceCode,第一个类的首个公用或静态方法
        /// </summary>
        public static object RunSourceCodeFirst(string sourceCode, object[] args = null)
        {
            try
            {
                string[] assemblies = getUsing(sourceCode).ToArray();           // 获取引用程序集
                string methodName = getFirstPublicMethod(sourceCode);           // 获取方法名
                bool isStatic = isPublicStaticMethod(sourceCode, methodName);   // 判断是否为静态方法

                return Run(sourceCode, "", methodName, args, isStatic, assemblies);    // 执行
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
        }


        /// <summary>
        /// 动态编译执行
        /// </summary>
        /// <param name="sourceCode">源码</param>
        /// <param name="classFullName">命名空间.类</param>
        /// <param name="methodName">方法名</param>
        /// <param name="args">方法参数</param>
        /// <param name="assemblies">引用程序集</param>
        /// <param name="isStaticMethod">是否为静态方法</param>
        static object Run(string sourceCode, string classFullName, string methodName, object[] args = null, bool isStaticMethod = false, string[] assemblies = null)
        {
            try
            {
                // 设置编译参数 System.Xml.dll
                CompilerParameters param = new CompilerParameters();
                param.GenerateExecutable = false;
                param.GenerateInMemory = true;

                // 添加常用的默认程序集
                param.ReferencedAssemblies.Add("Microsoft.CSharp.dll");
                param.ReferencedAssemblies.Add("mscorlib.dll");
                param.ReferencedAssemblies.Add("System.dll");
                param.ReferencedAssemblies.Add("System.Core.dll");
                param.ReferencedAssemblies.Add("System.Data.dll");
                param.ReferencedAssemblies.Add("System.Data.DataSetExtensions.dll");
                param.ReferencedAssemblies.Add("System.Drawing.dll");
                param.ReferencedAssemblies.Add("System.Windows.Forms.dll");
                param.ReferencedAssemblies.Add("System.Xml.dll");
                param.ReferencedAssemblies.Add("System.Xml.Linq.dll");

                if (assemblies != null)
                {
                    foreach (string name in assemblies)
                    {
                        string assembly = name + ".dll";
                        if (!param.ReferencedAssemblies.Contains(assembly))
                        {
                            param.ReferencedAssemblies.Add(assembly);
                        }
                    }
                }

                // 动态编译字符串代码
                CompilerResults result = new CSharpCodeProvider().CompileAssemblyFromSource(param, sourceCode);

                if (result.Errors.HasErrors)
                {
                    // 编译出错:
                    StringBuilder str = new StringBuilder();
                    foreach (CompilerError err in result.Errors)
                    {
                        str.AppendLine(err.ErrorText);
                    }
                    Console.WriteLine(str.ToString());
                    return str.ToString();
                }
                else
                {
                    // 编译通过:
                    Assembly assembly = result.CompiledAssembly;                // 获取已编译通过的程序集
                    if (classFullName == null || classFullName.Equals(""))      // 若未指定,则获取程序集第一个类路径名
                    {
                        classFullName = assembly.GetTypes()[0].FullName;
                    }

                    if (isStaticMethod)
                    {
                        // 调用程序集的静态方法: Type.InvokeMember
                        Type type = assembly.GetType(classFullName, true, true);

                        //object[] arg = new object[] { "参数1", "参数2" };
                        object tmp = type.InvokeMember(methodName, BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, null, args);
                        return tmp;
                    }
                    else
                    {
                        // 调用程序集类实例方法: method.Invoke
                        object obj = assembly.CreateInstance(classFullName);    // 创建一个类实例对象
                        MethodInfo method = obj.GetType().GetMethod(methodName);// 获取对象的对应方法

                        object tmp = method.Invoke(obj, args);                  // 调用对象的方法
                        return tmp;
                    }
                }
               
            }
            catch (Exception ex)
            {
                return ex.ToString();
            }
            Console.WriteLine("RUN OK");
        }

        #endregion

        #region 相关功能函数

        /// <summary>
        /// 获取文件中的数据,自动判定编码格式
        /// </summary>
        private static string fileToString(String filePath)
        {
            string str = "";

            //获取文件内容
            if (File.Exists(filePath))
            {
                StreamReader file1;

                file1 = new StreamReader(filePath, Encoding.UTF8);  // 读取文件中的数据
                str = file1.ReadToEnd();                            // 读取文件中的全部数据

                file1.Close();
                file1.Dispose();
            }
            return str;
        }

        /// <summary>
        /// 获取第一个公用方法
        /// </summary>
        /// <param name="sourceCode"></param>
        /// <returns></returns>
        private static string getFirstPublicMethod(string sourceCode)
        {
            string methodName = "";
            String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
            foreach (string iteam in lines)
            {
                string line = iteam.Trim();
                if (line.StartsWith("public ") && line.Contains("(") && line.Contains(")"))
                {
                    methodName = line.Substring(0, line.IndexOf("("));
                    methodName = methodName.Substring(methodName.LastIndexOf(" ") + 1);
                    break;
                }
            }
            return methodName;
        }

        /// <summary>
        /// 判断指定的方法是否为静态方法
        /// </summary>
        /// <returns></returns>
        private static bool isPublicStaticMethod(string sourceCode, string methodName)
        {
            bool isStatic = false;
            String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
            foreach (string iteam in lines)
            {
                string line = iteam.Trim();
                if (line.StartsWith("public ") && line.Contains(" " + methodName) && line.Contains("(") && line.Contains(")") && line.Contains("static"))
                {
                    isStatic = true;
                }
            }
            return isStatic;
        }

        /// <summary>
        /// 获取应用的程序集信息
        /// </summary>
        private static List<string> getUsing(string sourceCode)
        {
            String[] lines = sourceCode.Replace("\r\n", "\n").Split('\n');
            List<string> usings = new List<string>();
            foreach (string iteam in lines)
            {
                string line = iteam.Trim();
                if (line.StartsWith("using ") && line.EndsWith(";"))
                {
                    string usingAssembley = line.TrimEnd(';').Substring("using ".Length);
                    CheckAddAssembly(usings, usingAssembley);
                }
            }
            return usings;
        }

        /// <summary>
        /// 检测添加较短长度的Assembly名称
        /// </summary>
        private static void CheckAddAssembly(List<string> usings, string usingAssembley)
        {
            if (usings.Contains(usingAssembley)) return;
            for (int i = 0; i < usings.Count; i++)
            {
                string name = usings[i];
                if (usingAssembley.StartsWith(name + ".")) return;
                else if (name.StartsWith(usingAssembley + "."))
                {
                    usings[i] = usingAssembley;
                }
            }
            usings.Add(usingAssembley);
        }

        #endregion

    }
}

 

测试代码 将需的第三方库copy到执行器目录Newtonsoft.Json

 

 

 

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Excuter
{
   public class pp
    {
       public static void run()
        {

            Task.Run(()=>{

                Console.WriteLine("-----run ok");
                //var b = SqlHelper.GetProjectType(11);
                //Console.WriteLine(JsonConvert.SerializeObject(b));
            });
            Console.WriteLine("-----");
            //var a = SqlHelper.GetProjectType(11);
            //Console.WriteLine(JsonConvert.SerializeObject(a));
            Console.ReadKey();

        }
    }
    
    
    public class SqlHelper
    {
        public static string ConnString = @"data source=172.24.106.66;initial catalog=DXCCosmetics310;user id=sa;password=123456;max pool size=200;Pooling=true;";
        //ConfigurationManager.ConnectionStrings["sql"].ConnectionString;
        // @"server=6;uid=sa;pwd=;database=;";//
        //初始化SqlCommand对象
        public static void InitializeCommand(SqlCommand cmd, SqlConnection conn, SqlTransaction trans, CommandType cmdType, string cmdText, params SqlParameter[] paras)
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();
            cmd.Connection = conn;
            cmd.CommandText = cmdText;
            if (trans != null)
                cmd.Transaction = trans;
            cmd.CommandType = cmdType;
            if (paras != null)
                foreach (SqlParameter item in paras)
                {
                    cmd.Parameters.Add(item);
                }
        }

        //查询数据,返回相应的数据表
        public static DataTable GetDataTable(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras)
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn = new SqlConnection(connString))
            {
                InitializeCommand(cmd, conn, null, cmdType, cmdText, paras);
                using (SqlDataAdapter adapter = new SqlDataAdapter(cmd))
                {
                    DataTable dt = new DataTable();
                    adapter.Fill(dt);
                    cmd.Parameters.Clear();
                    return dt;
                }
            }
        }

        //查询单个数据,返回第一列第一行的数据
        public static object ExecuteScalar(string connString, CommandType cmdType, string cmdText, params SqlParameter[] paras)
        {
            SqlCommand cmd = new SqlCommand();
            using (SqlConnection conn = new SqlConnection(connString))
            {
                InitializeCommand(cmd, conn, null, cmdType, cmdText, paras);
                object obj = cmd.ExecuteScalar();
                cmd.Parameters.Clear();
                return obj;
            }
        }

        public static object GetProjectType(int projectCode)
        {
            //首先定义用于查询的SQL脚本
            string cmdText = @"SELECT top 10 * FROM ;";
            //使用SqlHelper操作类来读取表数据
            //定义一个用于存储读取过来的表数据DataTable对象
            try
            {
                DataTable dt = SqlHelper.GetDataTable(SqlHelper.ConnString, CommandType.Text, cmdText);

                return dt;
                //var dt = SqlHelper.ExecuteScalar(SqlHelper.ConnString, CommandType.Text, cmdText);
                //return dt;
            }
            catch (Exception ex)
            {

                LogHelper.Debug(JsonConvert.SerializeObject(ex));
            }
            return null;
        }
    }
    /// <summary>
    /// 打印Log
    /// </summary>
    public class LogHelper
    {
        static bool LogOff = false;
        public static string GetDirPath()
        {
            var Dic = AppDomain.CurrentDomain.BaseDirectory.Split('\\').ToList();
            if (Dic.Count <= 3)
            {
                return AppDomain.CurrentDomain.BaseDirectory + "\\logs";
            }
            var Dics = Dic.Take(Dic.Count - 3).ToArray();
            string path = string.Join("\\", Dics) + "\\logs";
            return path;
        }

        //在网站根目录下创建日志目录(bin文件夹→debug文件夹→logs文件夹)
        public static string path = GetDirPath();// @"..\..\logs\";// 

        //死锁
        public static object loglock = new object();

        public static void Debug(string content)
        {
            WriteLog("DEBUG", content);
        }

        public static void Info(string content)
        {
            WriteLog("INFO", content);
        }

        public static void Error(string content)
        {
            WriteLog("ERROR", content);
        }

        protected static void WriteLog(string type, string content)
        {
            if (LogOff)
            {
                return;
            }

            lock (loglock)
            {
                if (!Directory.Exists(path))//如果日志目录不存在就创建
                {
                    Directory.CreateDirectory(path);
                }

                string time = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff");//获取当前系统时间
                string filename = path + "/" + DateTime.Now.ToString("yyyy-MM-dd") + ".log";//用日期对日志文件命名

                //创建或打开日志文件,向日志文件末尾追加记录
                StreamWriter mySw = File.AppendText(filename);

                //向日志文件写入内容
                string write_content = time + " " + type + ": " + content;
                mySw.WriteLine(write_content);

                //关闭日志文件
                mySw.Close();
            }
        }
    }



}

 

posted @ 2021-11-24 15:36  一颗大白鲸  阅读(2295)  评论(0编辑  收藏  举报