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.pswp.cn/news/458782.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/458782.shtml
英文地址,請注明出處:http://en.pswp.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…

基于C++中常見內存錯誤的總結

在系統開發過程中出現的bug相對而言是比較好解決的&#xff0c;花費在這個上面的調試代價不是很大&#xff0c;但是在系統集成后的bug往往是難以定位的bug&#xff08;最好方式是打樁&#xff0c;通過打樁可以初步鎖定出錯的位置&#xff0c;如&#xff1a;進入函數前打印日志&…

UWP開發細節記錄:判斷文件類型

StorageFile.ContentType 屬性&#xff0c;是 string 類型&#xff0c;用來表示文件內容的 MIME 類型。例如&#xff0c;音樂文件可能有 "audio/mpeg" MIME 類型。(MSDN) MIME 類型的定義可以下面的鏈接找到&#xff1a; MIME Types - http://blogs.msdn.com/b/jaime…

Creating Apps With Material Design —— Creating Lists and Cards

轉載請注明 http://blog.csdn.net/eclipsexys 翻譯自Developer Android。時間倉促&#xff0c;有翻譯問題請留言指出&#xff0c;謝謝創建Lisst和Cards在你的應用程序創建復雜的清單&#xff0c;并與材料設計風格卡。您能夠使用RecyclerView和CardView部件。 創建RecyclerView …

計算機考研自命題院校雙非,計算機考研408——951211院校匯總

眾所周知&#xff0c;計算機考研408計算機學科基礎綜合難度與一些頂尖985自命題相比也是不落下風的&#xff0c;號稱最難工科專業課(請忽略912這種殿堂級別的)&#xff0c;難度大、知識點龐雜也是前些年眾多高校紛紛脫離408統考的原因。19年的計算機類考研火到爆炸&#xff0c;…

Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable)

第一次鼓搗Docker&#xff0c;- - ! 報錯&#xff1a; serverubuntu1987:~$ sudo apt-get update E: Could not get lock /var/lib/apt/lists/lock - open (11: Resource temporarily unavailable) E: Unable to lock directory /var/lib/apt/lists/ 轉載于:https://www.cnblo…

新手學Struts(一)----JSP+Servlet講解MVC實現原理

MVC基本原理一個簡單的例子改良的例子Struts基本流程的實現最近在學SSH&#xff08;Struts HibernateSpring)&#xff0c;這也算是一個比較經典的框架了&#xff0c;之前都是看人家大牛說這個框架&#xff0c;那個框架&#xff0c;說的真溜&#xff0c;自己也是佩服的五體投地啊…

中國首臺千萬億次超級計算機,中國首臺千萬億次超級計算機首批設備開始試用...

新華社天津&#xff11;月&#xff11;&#xff13;日電(記者 周潤健 羅捷)記者&#xff11;&#xff13;日從國家超級計算天津中心獲悉&#xff0c;中國首臺千萬億次超級計算機“天河一號”首批設備調試工作結束&#xff0c;具備向客戶提供服務的條件&#xff0c;“天河一號”…

Outlook Express 錯誤代碼表

錯誤碼 意義 一般 0x800C01310x800C013E 可能是 Folders.dbx 檔案屬性錯誤或損壞. 0x800CCC00 身份驗證&#xff08;Authentication&#xff09;未載入 0x800CCC01 認證&#xff08;Certificate&#xff09;內容錯誤 0x800CCC02 認證日期錯誤 0x800CCC03 使用者已聯機 0x800CCC…

USB設備枚舉過程

&#xff08;1&#xff09;集線器檢測新設備 &#xff08;集線器的英文稱為“Hub”&#xff09;主機集線器監視著每個端口的信號電壓&#xff0c;當有新設備接入時便可覺察。&#xff08;集線器端口的兩根信號線的每一根都有15kΩ的下拉電阻&#xff0c;而每一個設備在D都有一個…

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…

計算機工作原理 公開課,《計算機的基本工作原理》公開課材料(11頁)-原創力文檔...

《計算機系統的組成》教學設計教師&#xff1a;吳軍一、學習者分析初一的學生&#xff0c;具有活潑好動的特點&#xff0c;懷著對初中生活的憧憬來到一個新的環境里&#xff0c;對每樣事物都充滿著好奇&#xff0c;都想去探個究竟。隨著社會的進步&#xff0c; 計算機的使用范圍…

USB枚舉過程分析

1. 枚舉是什么? 枚舉就是從設備讀取一些信息&#xff0c;知道設備是什么樣的設備&#xff0c;如何進行通信&#xff0c;這樣主機就可以根據這些信息來加載合適的驅動程序。調試USB設備&#xff0c;很重要的一點就是USB的枚舉過程&#xff0c;只要枚舉成功了&#xff0c;那么就…

linux -- read(), write()

read()函數 2011-03-23 16:28:37| 分類&#xff1a; linux | 標簽&#xff1a; |字號大中小 訂閱 read函數從打開的設備或文件中讀取數據。 #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); 返回值&#xff1a;成功返回讀取的字節數&…

jquery的$.extend、$.fn.extend、 jQuery.extend( target, object1, [objectN])作用及區別

jQuery為開發插件提拱了兩個方法&#xff0c;分別是&#xff1a; jQuery.fn.extend();jQuery.extend(); 雖然 javascript 沒有明確的類的概念&#xff0c;但是用類來理解它&#xff0c;會更方便。 jQuery便是一個封裝得非常好的類&#xff0c;比如我們用 語句 $("#btn1&…

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;它都作為一種必備的家用電器來使用。由此可見電腦對我們 現代 人的重要性。但電腦畢…