利用反射动态调用C#嵌入到资源的托管DLL

来源:互联网 发布:人工智能创意文案 编辑:程序博客网 时间:2024/05/28 04:56

以前写了一篇博客《C#嵌入dll到资源释放的问题》讲到了DLL文件嵌入到资源后,程序运行时自动释放并实现代码调用的问题。很多读者都问到了同一个问题:文章针对的是非托管的Win 32 DLL,那么托管的DLL怎么嵌入并释放呢?这篇文章就来聊一下这个话题。

由于托管应用程序在启动时就需要加载全部使用到的托管DLL,所以采用嵌入Win32 DLL到资源然后再释放的方式是不可行的。有一种思路是在生成EXE后,把需要调用的DLL与EXE合并成一个新的EXE,比如IMerge等工具就可以实现这一过程(其实我也一直这么干)。但是今天我要讲的是一种类似嵌入非托管DLL的方式,利用反射直接通过代码来实现动态调用。

1 引用DLL

需要调用的托管math.dll主要代码:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace math{    public class math    {        public static int add(int a, int b)        {            return a + b;        }    }}

生成math.dll后,在需要调用的C#程序中添加对math.dll的引用:

1

2 嵌入DLL

具体嵌入步骤:

  1. 将引用的math修改属性:复制本地->False。

    2

  2. 将math.dll文件加入到调用程序功能的资源中,注意修改属性:生成操作->嵌入的资源。

    3

3 反射DLL

直接上代码:

using System;using System.Collections.Generic;using System.Linq;using System.Reflection;using System.Windows.Forms;using System.IO;namespace Demo{    static class Program    {        /// <summary>        /// 应用程序的主入口点。        /// </summary>        [STAThread]        static void Main()        {            Application.EnableVisualStyles();            Application.SetCompatibleTextRenderingDefault(false);            //反射            AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);            Application.Run(new Form1());        }        static Assembly CurrentDomain_AssemblyResolve(object sender, EventArgs e)        {            //从资源中加载DLL到内存            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Demo.math.dll"))            {                byte[] byData = new byte[stream.Length];                stream.Read(byData, 0, byData.Length);                return Assembly.Load(byData);            }        }    }}

我们现在就可以删除math.dll文件,直接运行生成的EXE程序,过程就这么简单。

原创粉丝点击