C# 运用(codeDom和反射技术)动态编译dll ,动态调用 |
您所在的位置:网站首页 › 反编译system类 › C# 运用(codeDom和反射技术)动态编译dll ,动态调用 |
在软件运用工程中,往往会根据各种各样,花样百出的需求来设计软件,在最近的项目中无意中,我就遇到了一个需求,据说是,客户要动态编译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 |