C#将dll打包到程序中

直接进入主题

先来看一个栗子,假设现在有一个第三方dll

namespace TestLibrary1
{public class Test{public void Point(){Console.WriteLine("aaabbbccc");}}
}
TestLibrary1.dll

在项目中引用,然后调用其中的方法Test,将输出aaabbbccc

using System;namespace ConsoleApplication5
{class Program{static void Main(string[] args){var test = new TestLibrary1.Test();test.Point();Console.ReadLine();}}
}

效果

但是很显然,当你把程序发给你的客户的时候必须要携带一个dll,否则就会这样

当程序在运行中,某个程序集加载失败的时候 会触发  AppDomain.CurrentDomain.AssemblyResolve 事件
//
// 摘要:
//     在对程序集的解析失败时发生。
public event ResolveEventHandler AssemblyResolve;

在这个事件中,可以重新为加载失败的程序集手动加载

如果你将dll作为资源文件打包的你的应用程序中(或者类库中)

就可以在硬盘加载失败的时候 从资源文件中加载对应的dll

就像这样:

class Program
{static Program(){
//这个绑定事件必须要在引用到TestLibrary1这个程序集的方法之前,注意是方法之前,不是语句之间,就算语句是在方法最后一行,在进入方法的时候就会加载程序集,如果这个时候没有绑定事件,则直接抛出异常,或者程序终止了AppDomain.CurrentDomain.AssemblyResolve
+= CurrentDomain_AssemblyResolve;}static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args){//获取加载失败的程序集的全名var assName = new AssemblyName(args.Name).FullName;if (args.Name == "TestLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"){//读取资源using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("ConsoleApplication5.TestLibrary1.dll")){var bytes = new byte[stream.Length];stream.Read(bytes, 0, (int)stream.Length);return Assembly.Load(bytes);//加载资源文件中的dll,代替加载失败的程序集 }}throw new DllNotFoundException(assName);}//程序进入方法之前会加载程序集,当程序集加载失败,则会进入CurrentDomain_AssemblyResolve事件static void Main(string[] args){var test = new TestLibrary1.Test();test.Point();Console.ReadLine();} }

这样就软件以一个exe单独运行了

以上都是我网上看来了...................


 

不过如果我有很多dll怎么办,总不至于每一个dll写一个分支吧?

所以我准备写一个通用的资源dll加载类

 

原理蛮简单的,主要是通过StackTrace类获取调用RegistDLL方法的对象,获取到对方的程序集

然后通过Assembly.GetManifestResourceNames()获取所有资源的名称

判断后缀名".dll"(这一步可以自由发挥),然后加载,以加载的程序集的名称为key保存到一个字典中

并绑定AppDomain.AssemblyResolve事件

在程序集加载失败时,从字典中查询同名程序集,如果有,直接从字典中加载

代码如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;namespace blqw
{/// <summary> 载入资源中的动态链接库(dll)文件/// </summary>static class LoadResourceDll{static Dictionary<string, Assembly> Dlls = new Dictionary<string, Assembly>();static Dictionary<string, object> Assemblies = new Dictionary<string, object>();static Assembly AssemblyResolve(object sender, ResolveEventArgs args){//程序集
            Assembly ass;//获取加载失败的程序集的全名var assName = new AssemblyName(args.Name).FullName;//判断Dlls集合中是否有已加载的同名程序集if (Dlls.TryGetValue(assName, out ass) && ass != null){Dlls[assName] = null;//如果有则置空并返回return ass;}else{throw new DllNotFoundException(assName);//否则抛出加载失败的异常
            }}/// <summary> 注册资源中的dll/// </summary>public static void RegistDLL(){//获取调用者的程序集var ass = new StackTrace(0).GetFrame(1).GetMethod().Module.Assembly;//判断程序集是否已经处理if (Assemblies.ContainsKey(ass.FullName)){return;}//程序集加入已处理集合Assemblies.Add(ass.FullName, null);//绑定程序集加载失败事件(这里我测试了,就算重复绑也是没关系的)AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve;//获取所有资源文件文件名var res = ass.GetManifestResourceNames();foreach (var r in res){//如果是dll,则加载if (r.EndsWith(".dll", StringComparison.OrdinalIgnoreCase)){try{var s = ass.GetManifestResourceStream(r);var bts = new byte[s.Length];s.Read(bts, 0, (int)s.Length);var da = Assembly.Load(bts);//判断是否已经加载if (Dlls.ContainsKey(da.FullName)){continue;}Dlls[da.FullName] = da;}catch{//加载失败就算了...
                    }}}}}
}
LoadResourceDll

代码下载

 

转载于:https://www.cnblogs.com/Percy_Lee/p/4865987.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458782.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Exchange 2016集成ADRMS系列-12:域内outlook 2010客户端测试

接下来&#xff0c;我们来到域内安装了office 2010的机器上进行测试。 首先我们在客户端上强制刷新组策略&#xff0c;把我们刚才设置的策略刷新下来。 然后我们可以运行gpresult /h result.html来看看策略是不是已经下来了。 策略下来之后&#xff0c;我们打开客户端上面的out…

如何用css和HTML结合画熊,结合伪元素实现的纯CSS3高级图形绘制

自小编上次整理了一些基础图形的绘制方法之后&#xff0c;大家都纷纷表示对css3的绘图技巧学习很有帮助。虽说万变不离其宗&#xff0c;再复杂的图形也可以用最简单的三角形或者圆弧组合出来&#xff0c;但仍有不少朋友反映&#xff0c;学会基本图形也不懂得怎样组合&#xff0…

新手学Struts(一)----JSP+Servlet讲解MVC实现原理

MVC基本原理一个简单的例子改良的例子Struts基本流程的实现最近在学SSH&#xff08;Struts HibernateSpring)&#xff0c;这也算是一个比较经典的框架了&#xff0c;之前都是看人家大牛说这个框架&#xff0c;那个框架&#xff0c;说的真溜&#xff0c;自己也是佩服的五体投地啊…

windows下apache+php+mysql 环境配置方法

转自&#xff1a;http://www.jb51.net/article/30128.htm 一 准备 1 下载apache http://httpd.apache.org/download.cgi#apache24 httpd-2.2.22-win32-x86-openssl-0.9.8t.msiopenssl表示带有openssl模块&#xff0c;利用openssl可给Apache配置SSL安全链接 2 下载php http://wi…

USB枚举过程分析

1. 枚举是什么? 枚举就是从设备读取一些信息&#xff0c;知道设备是什么样的设备&#xff0c;如何进行通信&#xff0c;这样主机就可以根据这些信息来加载合适的驱动程序。调试USB设备&#xff0c;很重要的一点就是USB的枚举过程&#xff0c;只要枚举成功了&#xff0c;那么就…

CATia对计算机配置要求,【2人回答】求CATIA对电脑的详细配置要求-3D溜溜网

回答&#xff1a;1、内存要求在32G和64G之间。2、硬盘要求选择7200转机械硬盘&#xff0c;4k以上分辨&#xff0c;就选择SSD固态硬盘。3、CPU要求睿频在4.1GHZ以上&#xff0c;核心在6和8核之间。4、显卡要求显存在6GB和11GB之间&#xff0c;位宽要求在192bit和384bit之间。5、…

如何制作自动更新程序?

原文出自&#xff1a;http://blog.csdn.net/metaphysis/article/details/18866631 如何制作自动更新程序&#xff1f; [版权所有 邱秋 2014 metaphysisyeah.net, 转载请注明出处] 最近为单位写了一个C/S结构的软件&#xff0c;这个软件是工作在单位的局域网内的。为了减轻为程序…

包含JS交互的混淆出错

2019独角兽企业重金招聘Python工程师标准>>> 小上司离职&#xff0c;我接手他负责的项目&#xff0c;进行版本更新的时候&#xff0c;在生成jar包测试的时候&#xff0c;点击按钮没有反应&#xff0c;页面是webview&#xff0c;按钮则是与js交互&#xff0c;logcat打…

计算机常用代码大全,常用电脑命令大全【图文】

导语 &#xff1a;电脑&#xff0c;这个在前几年貌似还离我们非常遥远的词汇&#xff0c;现在随着信息化社会的不断发展&#xff0c;已经走进了我们的千家万户。现在每一家新 装修 &#xff0c;它都作为一种必备的家用电器来使用。由此可见电脑对我们 现代 人的重要性。但电脑毕…

细数技术指标-[转载]

技术指标类别庞杂&#xff0c;要一一学全&#xff0c;基本不可能&#xff0c;也没有这个必要。我们只要掌握几个常用的指标&#xff0c;了解它们的原理&#xff0c;从而举一反三&#xff0c;就足够了。其实任何一种技术指标都是从形态、价格、量、时间这四项出发的&#xff0c;…

图论测试题(一)第一题:longest

第一题&#xff1a;longest 乌托邦有n个城市&#xff0c;某些城市之间有公路连接。任意两个城市都可以通过公路直接或者间接到达&#xff0c;并且任意两个城市之间有且仅有一条路径&#xff08;What does this imply? A tree!&#xff09;。 每条公路都有自己的长度&#xff0…

RTC实时时钟驱动

RTC&#xff08;Real-Time Clock)实时时钟为操作系统提供了一个可靠的时间&#xff0c;并且在断电的情况下&#xff0c;RTC实时时钟也可以通过电池供电&#xff0c;一直运行下去。 RTC通过STRB/LDRB这两个ARM指令向CPU传送8位数据&#xff08;BCD码&#xff09;。数据包括秒&am…

计算机表格复制粘贴后不变,excel表格复制粘贴后格式不变

Excel使用过程中经常需要将一个表格内容复制粘贴到其他表格中去。如果原始表格设置了行高和列宽&#xff0c;选中要复制的区域复制后&#xff0c;当在其他表格选择一个单元格进行粘贴时&#xff0c;行高和列宽就都变了。下面介绍excel表格复制粘贴后格式不变的操作方法。excel表…

C++ Primer章课后编程问题

1、代码#include<iostream> int main() {using namespace std;int num1;int num2;int total0;cout << "请输入開始数字\n";cin >> num1;cout << "请输入结束数字\n";cin >> num2;for (num1; num1<num2; num1)total num1…

vs 常见问题汇总

vs添加对dll的引用 我们在使用vs进行开发调试的时候经常会遇到一个问题&#xff0c;就是当我们的主工程引用到其他工程更新的dll&#xff08;我们经常采用copy到工程目录的方法&#xff09;、亦或者当我们的多个工程引用到同一个dll文件的时候&#xff0c;我们怎么来配置&#…

斯柯达柯珞克显示服务器错误,斯柯达柯珞克原来还有四驱的版本,不信你看!...

▶有望推出四驱版本▶专利图已经曝光▶外观没有变化斯柯达柯珞克大家应该不会特别陌生&#xff0c;虽然它在前两个月才正式上市&#xff0c;不过作为一款合资的紧凑型SUV来说&#xff0c;它的关注度还是不错的。销量上&#xff0c;4月份交出了2668辆的成绩&#xff0c;虽然还不…

javascript实例——鼠标特效篇(包含2个实例)

鼠标是现在电脑的基本配置之一&#xff0c;也是最常用的输入命令的工具之一。本文将将一些与鼠标有关系的特效。 1、跟随鼠标移动的彩色星星 如题&#xff0c;会根据鼠标的移动而移动&#xff0c;并在鼠标周围随机来回移动&#xff0c;让人感觉在放大缩小。根据书上的代码做了一…

Perforce使用指南_forP4V

第一章 前言 Perforce SCM System是一款构建于可伸缩客户/服务器结构之上的软件配置管理工具。仅仅应用 TCP/IP&#xff0c;开发人员就能够通过多种Perforce客户端&#xff08;几种平台的GUI、WEB、或命令行&#xff09;访问 Perforce服务器。Perforce能够被快速和容易地部署…

曙光服务器优势,5大核心优势 探秘曙光Cloudview三大平台

1Cloudview1.5核心优势对于云计算而言&#xff0c;国产厂商也有着自己独到的云方案。曙光Cloudview云计算操作系统采用新一代云计算中心的全新的管理模型&#xff0c;充分考虑云计算中心的资源分配、业务运行和运维服务等各种管理要素&#xff0c;实现云计算中心的软硬件平台资…

直连测速服务器异常,求证! 网件R7800, Speedtest测速的怪现象,200M宽带+R7800者进...

本帖最后由 毛毛雨 于 2017-11-18 18:50 编辑宽带是联通FTTH 200M&#xff0c;标准千兆网线&#xff0c;千兆网卡。问题前的插曲&#xff1a;R7800刚到手&#xff0c;就迫不及待的换上了&#xff0c;结果&#xff0c;无论是路由器内置Speedtest册数&#xff0c;还是电脑端的Spe…