.Net平台实现嵌入DLL C#描述

一、场景

  1. 开发小工具时需引用DLL,而部署分发时只希望提供执行文件。
  2. 在项目架构上隐藏某些DLL文件(文件结构层面)

二、原理

  1. DLL的加载是在使用时才被加载,而不是启动时(卸载是由垃圾回收器处理,无法预测回收时间)。
  2. AppDomain.CurrentDomain.AssemblyResolve事件可用于.Net框架加载程序集失败时手动控制重新加载程序集。
  3. DLL文件可作为资源内嵌进程序集。

三、实现要点

  1. 将DLL以“嵌入的资源”的形式加入项目。
  2. 引用DLL,并设置为“不复制到本地”。
  3. 在Main方法内利用AppDomain.CurrentDomain.AssemblyResolve事件手动控制加载DLL(也可在任意使用DLL前能够被执行到的地方订阅事件)。
  4. 保证在加载DLL成功前不以任何形式引用此DLL。
  5. 可同时实现对多个DLL及其他程序集进行加载。

四、示例代码

 1 using System;
 2 using System.Collections.Generic;
 3 using System.Linq;
 4 using System.Text;
 5 
 6 // 引入加载dll所需命名空间
 7 using System.Reflection;
 8 
 9 //using DllDemo;
10 // 错误,不要用任何方式调用dll,会导致未加载dll就依赖dll
11 
12 namespace AppDemo
13 {
14     class Program
15     {
16         static void Main(string[] args)
17         {
18             // 框架加载dll失败后执行,手动加载dll
19             AppDomain.CurrentDomain.AssemblyResolve += (sender, senderArgs) =>
20             {
21                 // 当前程序集
22                 var executingAssembly = Assembly.GetExecutingAssembly();
23                 // 当前程序集名称
24                 var assemblyName = new AssemblyName(executingAssembly.FullName).Name;
25                 // dll名称
26                 var dllName = new AssemblyName(senderArgs.Name).Name;
27                 // 待加载dll路径,指向当前程序集资源文件中dll路径。* 根据程序结构调整,使其正确指向dll
28                 var dllUri = assemblyName + "." + dllName + ".dll";
29                 // 加载dll
30                 using (var resourceStream = executingAssembly.GetManifestResourceStream(dllUri))
31                 {
32                     var assemblyData = new Byte[resourceStream.Length];
33                     resourceStream.Read(assemblyData, 0, assemblyData.Length);
34                     return Assembly.Load(assemblyData); //加载dll
35                 }
36             };
37             // app入口
38             AppDemo.Demo();
39             //var obj = new DllDemo.Dll();
40             //错误,不要用任何方式调用dll,会导致未加载dll就依赖dll
41             Console.Read();
42         }
43     }
44 }

  演示源码下载: https://files.cnblogs.com/kui2/DEMO-EmbeddedDllDemo.zip

五、另一个想法

  将DLL等资源文件内嵌程序集,执行时将其释放到磁盘上恢复所需文件。恩,费力不讨好而且容易被安全软件盯上的办法。非常时期可能会有用吧。

六、参考

posted @ 2012-11-29 20:28  夔奎  阅读(4218)  评论(4编辑  收藏  举报