? ? ? 在軟件運用工程中,往往會根據(jù)各種各樣,花樣百出的需求來設(shè)計軟件,在最近的項目中無意中,我就遇到了一個需求,據(jù)說是,客戶要動態(tài)編譯dll ,我“滴個乖乖”,這是要逆天??!
話不多說,直接來點干貨。
簡單分享一下個小demo:
1.運用codeDom技術(shù)實現(xiàn)動態(tài)程序集編譯。
? ? ? ? ? ? ? ? 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();//創(chuàng)建代碼生成器
? ? ? ? ? ? ? ? ICodeCompiler cc = cs.CreateCompiler();//實現(xiàn)并創(chuàng)建代碼編譯器實例
? ? ? ? ? ? ? ? CompilerParameters cp = new CompilerParameters();//編譯器的實例參數(shù)
? ? ? ? ? ? ? ? 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.運用反射技術(shù),根據(jù)程序集實例化類,并調(diào)用方法
? ? ? ? ? ? ? ? ? ? //Assembly ass = cr.CompiledAssembly;//動態(tài)編譯程序集(只限于動態(tài),當(dāng)程序連續(xù)動態(tài)編譯時只能加載出程序上次啟動得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.前端參數(shù):
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 特殊字符
{
? ? /// <summary>
? ? /// handle 的摘要說明
? ? /// </summary>
? ? 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);//當(dāng)前
? ? ? ? ? ? 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;//動態(tài)編譯程序集(只限于動態(tài),當(dāng)程序連續(xù)動態(tài)編譯時只能加載出程序上次啟動得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);//字符傳內(nèi)容簽名
? ? ? ? ? ? ? ? validate.signStr = resturnStr;
? ? ? ? ? ? ? ? validate.vernum = verNo;
? ? ? ? ? ? ? ? validate.Id = id;
? ? ? ? ? ? }
? ? ? ? ? ? return validate;
? ? ? ? ??
? ? ? ? }
? ? ? ? #endregion
? ? ? ? #region 數(shù)字簽名dll內(nèi)容
? ? ? ? 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;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? /// <summary>?
? ? ? ? /// 獲取時間戳?
? ? ? ? /// </summary>?
? ? ? ? /// <returns></returns>?
? ? ? ? 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; }
? ? }
}
以上代碼是基于后臺的角度對版本,和內(nèi)容匹配,添加相關(guān)邏輯。文章來源:http://www.zghlxwxcb.cn/news/detail-545251.html
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?----------------“天行健,君子以自強不息;地勢坤,君子以厚德載物”文章來源地址http://www.zghlxwxcb.cn/news/detail-545251.html
到了這里,關(guān)于C# 運用(codeDom和反射技術(shù))動態(tài)編譯dll ,動態(tài)調(diào)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!