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

这篇具有很好参考价值的文章主要介绍了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 特殊字符
{
    /// <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);//当前
            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;
            }
        }

        /// <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; }
    }
}

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

                                           ----------------“天行健,君子以自强不息;地势坤,君子以厚德载物”文章来源地址https://www.toymoban.com/news/detail-545251.html

到了这里,关于C# 运用(codeDom和反射技术)动态编译dll ,动态调用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • stable-diffusion.cpp 一个文件解决stable diffusion所有环境,不需要python,stable-diffusion.dll动态库C#调用Demo

    stable-diffusion.cpp 一个文件解决stable-diffusion所有环境,不需要python,stable-diffusion.dll动态库C#调用Demo 目录 介绍 效果 Text To Image Image To Image Upscale 项目 代码 Native.cs SDHelper.cs MainForm.cs 下载  stable-diffusion.cpp 地址:https://github.com/leejet/stable-diffusion.cpp StableDiffusionSharp 地址:https://

    2024年04月14日
    浏览(48)
  • C# 通过反射调用对象上的方法

    2024年02月13日
    浏览(48)
  • 【C#】反射机制,动态加载类文件

    【C#】编号生成器(定义单号规则、固定字符、流水号、业务单号) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129129787 【C#】日期范围生成器(开始日期、结束日期) 本文链接:https://blog.csdn.net/youcheng_ge/article/details/129040663 【C#】组件化开发,调用dll组件方法 本文链接

    2024年02月11日
    浏览(70)
  • Qt动态调用(外部调用)SDK库(dll动态库)

    ​​​​​​​  之前的文章,介绍了Qt调用sdk库的方式,大家可以点击查看(Q调用SDK库(dll动态库))之前的文章,里面介绍的调用方式就是静态的调用方式。如下图所示,需要提供.h文件,dll文件和lib文件。  本篇文章主要实现通过一个dll文件,外部动态调用的方式来调用我

    2024年02月09日
    浏览(40)
  • C#调用C++ dll教程

    在使用C#开发客户端时,有时需要调用C++ dll,本篇博客来介绍C#程序如何调用C++ dll。 首先使用VS2022创建C++ dll项目,具体步骤如下: (1)选择Windows桌面向导,点击下一步, 取项目名,例如我的dll项目名是libMath (2)选择动态项目,勾选导出符号 (3)编写动态代码,代码如下

    2024年01月25日
    浏览(41)
  • C#开发DLL,CAPL调用(CAPL>> .NET DLL)

    ret为dll里函数返回的值。 在visual studio中建立。

    2024年02月08日
    浏览(46)
  • C++调用C# dll成功示例

    一.准备C# dll类库 。生成CSLib.dll  二、写C++应用调用  1)需要把dll复制到运行目录下。(不然会提示找不到dll System.IO.FileNotFoundException:“未能加载文件或程序集“CSLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。系统找不到指定的文件) 2)设置\\\"公共语言运

    2024年02月14日
    浏览(60)
  • C#调用C++ dll异常排查

    最近在做的一款程序,长时间运行总会出现莫名的问题。有时是自动关闭,有时程序报错,有时调用的dll异常…… 由于开始与C++组合作时,使用其提供的dll出现过数据读写时异常(内存操作异常),于是怀疑他们提供的dll有内存泄漏。于是想通过日志或其它方法来确认这个猜

    2024年01月21日
    浏览(54)
  • C# DLL嵌套调用时修改生效

    C# DLL嵌套调用时,需要以被修改的DLL作为最下层,从下往上地重新生成所有DLL才可生效。 DLL1(最下层)代码: DLL2(中间层)代码: 应用程序代码: 实验步骤: 1.在代码无修改的情况下运行应用程序,输出结果为A。 2.修改DLL1动态链接库ConsoleWriteLineSomething方法,使其输出

    2024年01月25日
    浏览(63)
  • c++动态调用dll

    在C++中动态调用DLL(动态链接库)可以使用Windows API函数。以下是一个简单的示例,演示如何动态加载和调用DLL中的函数: 在上面的示例中,我们首先使用LoadLibrary函数加载DLL。然后,使用GetProcAddress函数获取要调用的函数的指针。在本例中,我们假设要调用的函数名为\\\"MyFu

    2024年01月24日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包