C# 运用(codeDom和反射技术)动态编译dll ,动态调用

您所在的位置:网站首页 反编译system类 C# 运用(codeDom和反射技术)动态编译dll ,动态调用

C# 运用(codeDom和反射技术)动态编译dll ,动态调用

2023-10-03 00:52| 来源: 网络整理| 查看: 265

      在软件运用工程中,往往会根据各种各样,花样百出的需求来设计软件,在最近的项目中无意中,我就遇到了一个需求,据说是,客户要动态编译dll ,我“滴个乖乖”,这是要逆天啊!

话不多说,直接来点干货。

简单分享一下个小demo:

1.运用codeDom技术实现动态程序集编译。

                string strExpre = "using System;" +                                   "using System.Collections.Generic;" +                                   "using System.Linq;" +                                    "using System.Web; " +                                    "namespace 特殊字符.Dll.Ver" + newVer + " " +                                     "{" +                                         "public class Test" +                                             "{" +                                             "" + newStr + "" +                                             "}" +                                     " }";                 CSharpCodeProvider cs = new CSharpCodeProvider();//创建代码生成器

                ICodeCompiler cc = cs.CreateCompiler();//实现并创建代码编译器实例

                CompilerParameters cp = new CompilerParameters();//编译器的实例参数

                cp.GenerateExecutable = false;//是否生成.exe

                cp.ReferencedAssemblies.Add("System.dll");//加载所需的dll

                cp.ReferencedAssemblies.Add("System.Core.dll");

                cp.OutputAssembly = path;

                CompilerResults cr = cc.CompileAssemblyFromSource(cp, strExpre);

               

                if (cr.Errors.HasErrors)

                {

                    //  Console.WriteLine(cr.Errors.ToString());                     Directory.Delete(HttpContext.Current.Server.MapPath(dir));                     throw new Exception();

                }

                else

                {

}

2.运用反射技术,根据程序集实例化类,并调用方法

                    //Assembly ass = cr.CompiledAssembly;//动态编译程序集(只限于动态,当程序连续动态编译时只能加载出程序上次启动得dll文件)                     //新编译出的文件路径                     string newComplierPath = HttpContext.Current.Server.MapPath(@"Dll\Ver" + newVer.ToString() + @"\Test.dll");

                    Assembly ass = Assembly.LoadFile(newComplierPath);

                    object obj = ass.CreateInstance("特殊字符.Dll.Ver" + newVer + ".Test");

                    MethodInfo mi = obj.GetType().GetMethod("save");

                    resulta = (int)mi.Invoke(obj, new object[] { num });

3.前端参数:

string newStr=public int save(int a){int b=a; return b;};

4.直接上完整代码:

using Microsoft.CodeDom.Providers.DotNetCompilerPlatform; using Newtonsoft.Json; using ReportSystem.DAL; using System; using System.CodeDom.Compiler; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.Remoting; using System.Security.Cryptography; using System.Text; using System.Web; using 特殊字符.Model;

namespace 特殊字符 {     ///     /// handle 的摘要说明     ///     public class handle : IHttpHandler     {

        public void ProcessRequest(HttpContext context)         {

            int resulta = 0;             var result = context.Request["content"];             var num = Convert.ToInt32(context.Request["num"]);                         var newStr = HttpUtility.UrlDecode(result);                          FileVerValidate vervalidateOld =getLastVerInfo();//旧版             string signStrNew = SHAEncryption(newStr);//当前             if (signStrNew == vervalidateOld.signStr)             {                 context.Response.Write("版本未变");             }             else             {                 string lastVerNo = vervalidateOld.vernum;                 double newVer = Convert.ToDouble(lastVerNo) + 1;

                string dir = @"Dll\Ver" + newVer.ToString();

                if (!Directory.Exists(dir))                 {                     Directory.CreateDirectory(HttpContext.Current.Server.MapPath(dir));                 }                 string path = HttpContext.Current.Server.MapPath(dir + @"\AccountTest.dll");

                string strExpre = "using System;" +                                   "using System.Collections.Generic;" +                                   "using System.Linq;" +                                    "using System.Web; " +                                    "namespace 特殊字符.Dll.Ver" + newVer + " " +                                     "{" +                                         "public class AccountTest" +                                             "{" +                                             "" + newStr + "" +                                             "}" +                                     " }";

                CSharpCodeProvider cs = new CSharpCodeProvider();

                ICodeCompiler cc = cs.CreateCompiler();

                CompilerParameters cp = new CompilerParameters();

                cp.GenerateExecutable = false;

                cp.ReferencedAssemblies.Add("System.dll");

                cp.ReferencedAssemblies.Add("System.Core.dll");

                cp.OutputAssembly = path;

                CompilerResults cr = cc.CompileAssemblyFromSource(cp, strExpre);

               

                if (cr.Errors.HasErrors)

                {

                    //  Console.WriteLine(cr.Errors.ToString());                     Directory.Delete(HttpContext.Current.Server.MapPath(dir));                     throw new Exception();

                }

                else

                {

                    //Assembly ass = cr.CompiledAssembly;//动态编译程序集(只限于动态,当程序连续动态编译时只能加载出程序上次启动得dll文件)                     //新编译出的文件路径                     string newComplierPath = HttpContext.Current.Server.MapPath(@"Dll\Ver" + newVer.ToString() + @"\AccountTest.dll");

                    Assembly ass = Assembly.LoadFile(newComplierPath);

                    object obj = ass.CreateInstance("特殊字符.Dll.Ver" + newVer + ".AccountTest");

                    MethodInfo mi = obj.GetType().GetMethod("save");

                    resulta = (int)mi.Invoke(obj, new object[] { num });

                    string sql = "insert into DynamicDllVerRecord values('" + newStr + "','" + newVer.ToString() + "','" + GetTimeStamp() + "',0,'Mr.Wang','"+DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")+"');" +                                  "update DynamicDllVerRecord set TimeStamp='' where Id=" + vervalidateOld.Id + "";                     int resultNum = SQLHelper.ExecuteNonQuerySQL(sql);

                }             }             context.Response.Write(resulta);         }         #region 获得上次版本信息

               private  FileVerValidate getLastVerInfo() {             FileVerValidate validate = new FileVerValidate();             string sql = "select top(1)Id,Ver,FunStr from DynamicDllVerRecord where TimeStamp'' order by CreateDate desc;;";             DataTable obj=SQLHelper.ExecuteDataTableSQL(sql);

            string sql2 = "select top(1)Id,Ver,FunStr from DynamicDllVerRecord order by CreateDate desc;";             DataTable obj2 = SQLHelper.ExecuteDataTableSQL(sql2);             string verNo = "";             string funStr = string.Empty;             int id = 0;             if (obj2.Rows.Count == 0)             {                 verNo = "";                 funStr = "";                 id = 0;             }             else if (obj.Rows.Count == 0 && obj2.Rows.Count != 0)             {                 verNo = obj2.Rows[0]["Ver"].ToString();                 funStr = obj2.Rows[0]["FunStr"].ToString();                 id= Convert.ToInt32(obj2.Rows[0]["Id"].ToString());             }             else if (obj.Rows.Count != 0 && obj2.Rows.Count != 0)             {                 verNo = obj.Rows[0]["Ver"].ToString();                 funStr = obj.Rows[0]["FunStr"].ToString();                 id = Convert.ToInt32(obj.Rows[0]["Id"].ToString());             }                          if (funStr != "")             {

             

                string resturnStr = SHAEncryption(funStr);//字符传内容签名

                validate.signStr = resturnStr;

                validate.vernum = verNo;

                validate.Id = id;

            }

            return validate;           

        }

        #endregion

        #region 数字签名dll内容

        public static string SHAEncryption(string FunStr)         {

            byte[] bytes = Encoding.Default.GetBytes(FunStr);             SHA1 sha = new SHA1Managed();             byte[] result_byte = sha.ComputeHash(bytes);             return Convert.ToBase64String(result_byte);         }

        #endregion         public bool IsReusable         {             get             {                 return false;             }         }

        ///           /// 获取时间戳          ///           ///           public static string GetTimeStamp()         {             TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);             return Convert.ToInt64(ts.TotalSeconds).ToString();         }     }

    public class  FileVerValidate {

        public int Id { set; get; }

        public  string vernum { set; get; }

        public  string signStr { set; get; }     } }

以上代码是基于后台的角度对版本,和内容匹配,添加相关逻辑。

                                           ----------------“天行健,君子以自强不息;地势坤,君子以厚德载物”



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3