最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C#將dll打包到程序中的具體實現(xiàn)

 更新時間:2013年10月16日 15:15:07   作者:  
這篇文章介紹了C#將dll打包到程序中的具體實現(xiàn),有需要的朋友可以參考一下

直接進入主題

先來看一個栗子,假設(shè)現(xiàn)在有一個第三方dll

復制代碼 代碼如下:

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


TestLibrary1.dll

在項目中引用,然后調(diào)用其中的方法Test,將輸出aaabbbccc

復制代碼 代碼如下:

using System;

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


效果

但是很顯然,當你把程序發(fā)給你的客戶的時候必須要攜帶一個dll,否則就會這樣

當程序在運行中,某個程序集加載失敗的時候 會觸發(fā)  AppDomain.CurrentDomain.AssemblyResolve 事件

復制代碼 代碼如下:

//
// 摘要:
//     在對程序集的解析失敗時發(fā)生。
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單獨運行了

以上都是我網(wǎng)上看來了...................

--------------------------------------------------------------------------------
不過如果我有很多dll怎么辦,總不至于每一個dll寫一個分支吧?

所以我準備寫一個通用的資源dll加載類

原理蠻簡單的,主要是通過StackTrace類獲取調(diào)用RegistDLL方法的對象,獲取到對方的程序集

然后通過Assembly.GetManifestResourceNames()獲取所有資源的名稱

判斷后綴名".dll"(這一步可以自由發(fā)揮),然后加載,以加載的程序集的名稱為key保存到一個字典中

并綁定AppDomain.AssemblyResolve事件

在程序集加載失敗時,從字典中查詢同名程序集,如果有,直接從字典中加載

代碼如下:

復制代碼 代碼如下:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;

namespace blqw
{
    /// <summary> 載入資源中的動態(tài)鏈接庫(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()
        {
            //獲取調(diào)用者的程序集
            var ass = new StackTrace(0).GetFrame(1).GetMethod().Module.Assembly;
            //判斷程序集是否已經(jīng)處理
            if (Assemblies.ContainsKey(ass.FullName))
            {
                return;
            }
            //程序集加入已處理集合
            Assemblies.Add(ass.FullName, null);
            //綁定程序集加載失敗事件(這里我測試了,就算重復綁也是沒關(guān)系的)
            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);
                        //判斷是否已經(jīng)加載
                        if (Dlls.ContainsKey(da.FullName))
                        {
                            continue;
                        }
                        Dlls[da.FullName] = da;
                    }
                    catch
                    {
                        //加載失敗就算了...
                    }
                }
            }
        }
    }
}


LoadResource.Dll

相關(guān)文章

  • C# 使用GDI繪制雷達圖的實例

    C# 使用GDI繪制雷達圖的實例

    這篇文章主要介紹了C# 使用GDI繪制雷達圖,本文通過一段實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-11-11
  • 利用C#開發(fā)瀏覽器擴展的全過程記錄

    利用C#開發(fā)瀏覽器擴展的全過程記錄

    做web開發(fā)的同學,經(jīng)常會用到各種chrome瀏覽器插件,那么我們寄幾怎么開發(fā)一個插件呢(其實是瀏覽器擴展)?這篇文章主要給大家介紹了關(guān)于利用C#開發(fā)瀏覽器擴展的相關(guān)資料,需要的朋友可以參考下
    2021-07-07
  • WinForm調(diào)用jar包的方法分析

    WinForm調(diào)用jar包的方法分析

    這篇文章主要介紹了WinForm調(diào)用jar包的方法,結(jié)合實例形式分析了WinForm調(diào)用jar包的原理、實現(xiàn)技巧與相關(guān)注意事項,需要的朋友可以參考下
    2017-05-05
  • C#操作串口通信協(xié)議Modbus的常用方法介紹

    C#操作串口通信協(xié)議Modbus的常用方法介紹

    這篇文章介紹了C#操作串口通信協(xié)議Modbus的常用方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-05-05
  • C#實現(xiàn)QQ截圖功能及相關(guān)問題

    C#實現(xiàn)QQ截圖功能及相關(guān)問題

    這篇文章主要為大家詳細介紹了C#實現(xiàn)QQ截圖功能及相關(guān)問題,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • C# 中的委托與事件機制詳解

    C# 中的委托與事件機制詳解

    本文詳細介紹了C#中委托和事件的概念、使用方法和應用場景,包括委托定義、匿名方法、Lambda表達式、事件機制和多播委托的詳細說明,委托作為類型安全的函數(shù)指針,文章還探討了如何通過匿名方法和Lambda表達式簡化委托的使用,以及多播委托在事件處理中的應用
    2024-10-10
  • C#實現(xiàn)txt定位指定行完整實例

    C#實現(xiàn)txt定位指定行完整實例

    這篇文章主要介紹了C#實現(xiàn)txt定位指定行的方法,涉及C#針對文本文件進行光標定位的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-08-08
  • c#獲取字符串寬度的示例代碼(字節(jié)數(shù)方法)

    c#獲取字符串寬度的示例代碼(字節(jié)數(shù)方法)

    本篇文章主要介紹了c#獲取字符串寬度的示例代碼(字節(jié)數(shù)方法)。需要的朋友可以過來參考下,希望對大家有所幫助
    2014-01-01
  • 基于不要返回null之EmptyFactory的應用詳解

    基于不要返回null之EmptyFactory的應用詳解

    本篇文章對不要返回null之EmptyFactory進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • c#繼承與多態(tài)使用示例

    c#繼承與多態(tài)使用示例

    繼承是面向?qū)ο蟪绦蛟O(shè)計的主要特征之一,允許重用現(xiàn)有類去創(chuàng)建新類的過程。下面使用示例學習一下c#繼承與多態(tài)
    2014-01-01

最新評論

左贡县| 罗山县| 高州市| 兰溪市| 遂平县| 磐安县| 广饶县| 阳朔县| 思茅市| 遂溪县| 麟游县| 安徽省| 攀枝花市| 邵武市| 镇雄县| 长葛市| 平罗县| 南部县| 神池县| 宜章县| 庆云县| 紫阳县| 文成县| 北流市| 珲春市| 揭西县| 广宁县| 南陵县| 慈溪市| 丘北县| 全椒县| 太和县| 西宁市| 荥经县| 南阳市| 阿拉善右旗| 革吉县| 崇仁县| 宿迁市| 西华县| 石屏县|