国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項超值服

開通VIP
什么是程序集 - 而立的日志 - 網(wǎng)易博客

什么是程序集

c# 2010-01-06 10:23:28 閱讀146 評論0   字號: 訂閱

程序集是任何 .NET Framework 應(yīng)用程序的基本構(gòu)造塊。例如,在生成簡單的 C# 應(yīng)用程序時,Visual Studio 創(chuàng)建一個單個可移植可執(zhí)行 (PE) 文件形式的程序集,明確地說就是一個 EXE 或 DLL。

程序集包含描述它們自己的內(nèi)部版本號和它們包含的所有數(shù)據(jù)和對象類型的詳細(xì)信息的元數(shù)據(jù)。

程序集僅在需要時才加載。如果不使用程序集,則不會加載。這意味著程序集可能是在大型項目中管理資源的有效途徑。

程序集可以包含一個或多個模塊。例如,計劃較大的項目時,可以讓幾個各個開發(fā)人員負(fù)責(zé)單獨(dú)的模塊,并通過組合所有這些模塊來創(chuàng)建單個程序集。

一、程序集概述

程序集具有以下特點(diǎn):

·程序集作為 .exe 或 .dll 文件實(shí)現(xiàn)。

·通過將程序集放在全局程序集緩存中,可在多個應(yīng)用程序之間共享程序集。

·要將程序集包含在全局程序集緩存中,必須對程序集進(jìn)行強(qiáng)命名。

·程序集僅在需要時才加載到內(nèi)存中。

·可以使用反射以編程方式獲取關(guān)于程序集的信息。

·如果加載程序集的目的只是對其進(jìn)行檢查,應(yīng)使用諸如 ReflectionOnlyLoadFrom 的方法。

·可以在單個應(yīng)用程序中使用相同程序集的兩個版本。

 二、友元程序集

      可以從一個程序集訪問另一個程序集中的內(nèi)部類型或內(nèi)部成員。

備注:

友元程序集功能用于訪問內(nèi)部成員;私有類型和私有成員仍然不可訪問。

若要使程序集(程序集 B)能夠訪問另一個程序集(程序集 A)的內(nèi)部類型和成員,應(yīng)使用程序集 A 中的 InternalsVisibleToAttribute 屬性。

說明:

在對將要訪問另一個程序集(程序集 A)的內(nèi)部類型或內(nèi)部成員的程序集(程序集 B)進(jìn)行編譯時,必須用 /out 編譯器選項顯式指定輸出文件的名稱(.exe 或 .dll)。這是必需的,因?yàn)楫?dāng)編譯器將生成的程序集綁定到外部引用時,尚未為該程序集生成名稱。

StrongNameIdentityPermission 類還提供共享類型的功能,其與友元程序集的區(qū)別如下:

·StrongNameIdentityPermission 應(yīng)用于單個類型,而友元程序集應(yīng)用于整個程序集。

·如果希望程序集 B 能夠共享程序集 A 中的數(shù)百個類型,則必須使用 StrongNameIdentityPermission 修飾所有這些類型;而使用友元程序集時只需聲明一次友元關(guān)系。

·使用 StrongNameIdentityPermission 時,想要共享的類型必須聲明為公共類型。使用友元程序集時,會將共享類型聲明為內(nèi)部類型。

·有關(guān)如何生成可訪問程序集中的非公共類型的 .netmodule 的信息,請參見 /moduleassemblyname。

示例

在此示例中,程序集使內(nèi)部類型和內(nèi)部成員對名為 called cs_friend_assemblies_2 的程序集可見。

 

// cs_friend_assemblies.cs

// compile with: /target:library

using System.Runtime.CompilerServices;

using System;

 

[assembly:InternalsVisibleTo("cs_friend_assemblies_2")]

 

// internal by default

class Class1

{

    public void Test()

    {

        Console.WriteLine("Class1.Test");

    }

}

 

// public type with internal member

public class Class2

{

    internal void Test()

    {

        Console.WriteLine("Class2.Test");

    }

}

在此示例中,程序集使用程序集 cs_friend_assemblies.dll 中的內(nèi)部類型和內(nèi)部成員。

注意,必須顯式指定輸出文件的名稱 (/out:cs_friend_assemblies_2.exe)。

如果此程序集允許另一個程序集(程序集 C)訪問它的內(nèi)部類型和成員,則程序集 C 不會自動變成程序集 cs_friend_assemblies.dll 的友元。

 

// cs_friend_assemblies_2.cs

// compile with: /reference:cs_friend_assemblies.dll /out:cs_friend_assemblies_2.exe

public class M

{

    static void Main()

    {

        // access an internal type

        Class1 a = new Class1();

        a.Test();

 

        Class2 b = new Class2();

        // access an internal member of a public type

        b.Test();

    }

}

 

Class1.Test

Class2.Test

此示例演示了如何使內(nèi)部類型和成員對具有強(qiáng)名稱的程序集可用。

若要生成 keyfile 并顯示公鑰,請使用下面的 sn.exe 命令序列:

·sn -k friend_assemblies.snk // 生成強(qiáng)名稱密鑰

·sn -p friend_assemblies.snk key.publickey // 將公鑰從 key.snk 提取到 key.publickey 中

·sn -tp key.publickey // 顯示存儲在文件 key.publickey 中的公鑰

用 /keyfile 將 keyfile 傳遞到編譯器。

 

// cs_friend_assemblies_3.cs

// compile with: /target:library /keyfile:friend_assemblies.snk

using System.Runtime.CompilerServices;

 

[assembly:InternalsVisibleTo("cs_friend_assemblies_4, PublicKey=0024000004800000940000000602000000240000525341310004000001000100031d7b6f3abc16c7de526fd67ec2926fe68ed2f9901afbc5f1b6b428bf6cd9086021a0b38b76bc340dc6ab27b65e4a593fa0e60689ac98dd71a12248ca025751d135df7b98c5f9d09172f7b62dabdd302b2a1ae688731ff3fc7a6ab9e8cf39fb73c60667e1b071ef7da5838dc009ae0119a9cbff2c581fc0f2d966b77114b2c4")]

class Class1

{

    public void Test()

    {

        System.Console.WriteLine("Class1.Test");

    }

}

此示例演示如何使用對具有強(qiáng)名稱的程序集可用的內(nèi)部類型和成員。

// cs_friend_assemblies_4.cs

// compile with: /keyfile:friend_assemblies.snk /reference:cs_friend_assemblies_3.dll /out:cs_friend_assemblies_4.exe

public class M

{

    static void Main()

    {

        Class1 a = new Class1();

        a.Test();

    }

}

 

三、如何:與其他應(yīng)用程序共享程序集

      程序集可以是私有的也可以是共享的:默認(rèn)情況下,大多數(shù)簡單的 C# 程序都包含一個私有程序集,原因是不打算將該程序集供其他應(yīng)用程序使用。

為了與其他應(yīng)用程序共享程序集,必須將該程序集置于 全局程序集緩存 (GAC) 中。

共享程序集:

·創(chuàng)建程序集。

·為程序集指定一個強(qiáng)名稱。

·為程序集指定版本信息。

·將您的程序集添加到全局程序集緩存中。

·從其他應(yīng)用程序中訪問該程序集包含的類型。

 

四、如何:加載和卸載程序集

      程序引用的程序集將在生成時自動加載,不過也可以在運(yùn)行時將特定的程序集加載到當(dāng)前應(yīng)用程序域中。

沒有辦法卸載單獨(dú)的程序集而不卸載包含它的所有應(yīng)用程序域。即使程序集已在范圍之外,實(shí)際的程序集文件仍然保持被加載,直至包含它的所有應(yīng)用程序域都被卸載。

如果想要卸載某些程序集而不卸載其他程序集,可考慮創(chuàng)建新的應(yīng)用程序域,在該域中執(zhí)行代碼,然后卸載該應(yīng)用程序域。

將程序集加載到應(yīng)用程序域中:

·使用 AppDomain 和 System.Reflection 類中包含的幾個加載方法之一。有關(guān)更多信息,請參見將程序集加載到應(yīng)用程序域中。

卸載應(yīng)用程序域:

·沒有辦法卸載單獨(dú)的程序集而不卸載包含它的所有應(yīng)用程序域。使用 AppDomain 中的 Unload 方法可卸載應(yīng)用程序域。

 

五、如何:確定文件是否為程序集

      當(dāng)且僅當(dāng)一個文件是托管文件并且在其元數(shù)據(jù)中包含程序集入口時,該文件才是一個程序集。

如何手動確定一個文件是否為程序集:

·啟動 MSIL 反匯編程序 (Ildasm.exe)。

·加載希望測試的文件。

·如果 ILDASM 報告該文件不是可移植的可執(zhí)行 (PE) 文件,則它不是程序集。有關(guān)更多信息,請參見主題 如何:查看程序集內(nèi)容。

如何以編程方式確定一個文件是否為程序集:

·調(diào)用 GetAssemblyName 方法,并向其傳遞正在測試的文件的完整文件路徑和名稱。

·如果引發(fā) BadImageFormatException 異常,則該文件不是程序集。

示例:

此示例測試一個 DLL 以確定它是否為程序集。

class TestAssembly

{

    static void Main()

    {

 

        try

        {

            System.Reflection.AssemblyName testAssembly =

                System.Reflection.AssemblyName.GetAssemblyName(@"C:\Windows\Microsoft.NET\Framework\v3.5\System.Net.dll");

 

            System.Console.WriteLine("Yes, the file is an Assembly.");

        }

 

        catch (System.IO.FileNotFoundException)

        {

            System.Console.WriteLine("The file cannot be found.");

        }

 

        catch (System.BadImageFormatException)

        {

            System.Console.WriteLine("The file is not an Assembly.");

        }

 

        catch (System.IO.FileLoadException)

        {

            System.Console.WriteLine("The Assembly has already been loaded.");

        }

    }

}

/* Output (with .NET Framework 3.5 installed):

    Yes, the file is an Assembly.

*/

GetAssemblyName 方法加載測試文件,然后在讀取信息之后釋放它。

 

六、extern

      extern 修飾符用于聲明在外部實(shí)現(xiàn)的方法。extern 修飾符的常見用法是在使用 Interop 服務(wù)調(diào)入非托管代碼時與 DllImport 屬性一起使用。在這種情況下,還必須將方法聲明為 static,如下示例所示:

[DllImport("avifil32.dll")]private static extern void AVIFileInit();extern 關(guān)鍵字還可以定義外部程序集別名,使得可以從單個程序集中引用同一組件的不同版本。

將 abstract 和 extern 修飾符一起使用來修改同一成員是錯誤的。使用 extern 修飾符意味著方法在 C# 代碼的外部實(shí)現(xiàn),而使用 abstract 修飾符意味著在類中未提供方法實(shí)現(xiàn)。

      extern 關(guān)鍵字在使用上比在 C++ 中有更多限制。

示例

在該示例中,程序接收來自用戶的字符串并將該字符串顯示在消息框中。程序使用從 User32.dll 庫導(dǎo)入的 MessageBox 方法。

//using System.Runtime.InteropServices;

class ExternTest

{

    [DllImport("User32.dll", CharSet=CharSet.Unicode)]

    public static extern int MessageBox(int h, string m, string c, int type);

 

    static int Main()

    {

        string myString;

        Console.Write("Enter your message: ");

        myString = Console.ReadLine();

        return MessageBox(0, myString, "My Message Box", 0);

    }

 

}

此示例使用 C 程序創(chuàng)建一個 DLL,在下一示例中將從 C# 程序調(diào)用該 DLL。

// cmdll.c

// Compile with: /LD

int __declspec(dllexport) SampleMethod(int i)

{

   return i*10;

}

該示例使用兩個文件 CM.cs 和 Cmdll.c 來說明 extern。C 文件是示例 2 中創(chuàng)建的外部 DLL,它從 C# 程序內(nèi)調(diào)用。

// cm.cs

using System;

using System.Runtime.InteropServices;

public class MainClass

{

   [DllImport("Cmdll.dll")]

   public static extern int SampleMethod(int x);

 

   static void Main()

   {

      Console.WriteLine("SampleMethod() returns {0}.", SampleMethod(5));

   }

}

SampleMethod() returns 50.

 

七、公共語言運(yùn)行庫中的程序集

1、程序集概述

      程序集是 .NET Framework 編程的基本組成部分。程序集執(zhí)行以下功能:

·包含公共語言運(yùn)行庫執(zhí)行的代碼。如果可移植可執(zhí)行 (PE) 文件沒有相關(guān)聯(lián)的程序集清單,則將不執(zhí)行該文件中的 Microsoft 中間語言 (MSIL) 代碼。請注意,每個程序集只能有一個入口點(diǎn)(即 DllMain、WinMain 或 Main)。

·程序集形成安全邊界。程序集就是在其中請求和授予權(quán)限的單元。

·程序集形成類型邊界。每一類型的標(biāo)識均包括該類型所駐留的程序集的名稱。在一個程序集范圍內(nèi)加載的 MyType 類型不同于在其他程序集范圍內(nèi)加載的 MyType 類型。

·程序集形成引用范圍邊界。程序集的清單包含用于解析類型和滿足資源請求的程序集元數(shù)據(jù)。它指定在該程序集之外公開的類型和資源。該清單還枚舉它所依賴的其他程序集。

·程序集形成版本邊界。程序集是公共語言運(yùn)行庫中最小的可版本化單元,同一程序集中的所有類型和資源均會被版本化為一個單元。程序集的清單描述您為任何依賴項程序集所指定的版本依賴性。

·程序集形成部署單元。當(dāng)一個應(yīng)用程序啟動時,只有該應(yīng)用程序最初調(diào)用的程序集必須存在。其他程序集(例如本地化資源和包含實(shí)用工具類的程序集)可以按需檢索。這就使應(yīng)用程序在第一次下載時保持精簡。

·程序集是支持并行執(zhí)行的單元。

程序集可以是靜態(tài)的或動態(tài)的。靜態(tài)程序集可以包括 .NET Framework 類型(接口和類),以及該程序集的資源(位圖、JPEG 文件、資源文件等)。靜態(tài)程序集存儲在磁盤上的可移植可執(zhí)行 (PE) 文件中。您還可以使用 .NET Framework 來創(chuàng)建動態(tài)程序集,動態(tài)程序集直接從內(nèi)存運(yùn)行并且在執(zhí)行前不存儲到磁盤上。您可以在執(zhí)行動態(tài)程序集后將它們保存在磁盤上。

有幾種創(chuàng)建程序集的方法。您可以使用過去用來創(chuàng)建 .dll 或 .exe 文件的開發(fā)工具,例如 Visual Studio 2005。您可以使用 Windows 軟件開發(fā)工具包 (SDK) 中提供的工具來創(chuàng)建帶有在其他開發(fā)環(huán)境中創(chuàng)建的模塊的程序集。您還可以使用公共語言運(yùn)行庫 API(例如 Reflection.Emit)來創(chuàng)建動態(tài)程序集。

 

2、程序集優(yōu)點(diǎn)

      程序集旨在簡化應(yīng)用程序部署并解決在基于組件的應(yīng)用程序中可能出現(xiàn)的版本控制問題。

最終用戶和開發(fā)人員比較熟悉當(dāng)今基于組件的系統(tǒng)所產(chǎn)生的版本控制和部署問題。一些最終用戶曾經(jīng)歷過在計算機(jī)上安裝新應(yīng)用程序失敗的事情,發(fā)現(xiàn)已有應(yīng)用程序突然停止工作。許多開發(fā)人員花費(fèi)了大量的時間來使所有必需的注冊表項保持一致,以便激活 COM 類。

通過在 .NET Framework 中使用程序集,許多開發(fā)問題得以解決。因?yàn)槌绦蚣遣灰蕾囉谧员眄椀淖允鼋M件,所以程序集使無相互影響的應(yīng)用程序安裝成為可能。程序集還使應(yīng)用程序的卸載和復(fù)制得以簡化。

版本控制問題:

·目前,Win32 應(yīng)用程序存在兩類版本控制問題:

·版本控制規(guī)則不能在應(yīng)用程序的各段之間表達(dá),并且不能由操作系統(tǒng)強(qiáng)制實(shí)施。目前的辦法依賴于向后兼容,而這通常很難保證。接口定義一經(jīng)發(fā)布就必須是靜態(tài)的,并且單段代碼必須保持與以前版本向后兼容。此外,通常要對代碼進(jìn)行設(shè)計,以便在任意給定時間在計算機(jī)上只能出現(xiàn)和執(zhí)行代碼的一個版本。

·沒有辦法在創(chuàng)建到一起的多套組件集與運(yùn)行時提供的那套組件之間保持一致。

這兩類版本控制問題結(jié)合在一起產(chǎn)生了 DLL 沖突,在這些沖突中,安裝一個應(yīng)用程序可能會無意間破壞現(xiàn)有的應(yīng)用程序,因?yàn)樗惭b的某個軟件組件或 DLL 與以前的版本不完全向后兼容。出現(xiàn)此情況后,系統(tǒng)不支持診斷和解決此問題。

 

最終解決 DLL 沖突:

Microsoft? Windows? 2000 開始致力于解決這些問題。它所提供的兩個功能可以部分地解決 DLL 沖突:

·Windows 2000 使您能夠創(chuàng)建這樣的客戶端應(yīng)用程序,其中的 .dll 依賴文件與該應(yīng)用程序的 .exe 文件位于相同的目錄中。Windows 2000 經(jīng)過配置,能夠在檢查完全限定的路徑或搜索常規(guī)路徑前,檢查 .exe 文件所在目錄中的組件。這使組件可以獨(dú)立于其他應(yīng)用程序所安裝和使用的組件。

·Windows 2000 鎖定 System32 目錄中隨操作系統(tǒng)提供的文件,使這些文件不會在安裝應(yīng)用程序時被無意替換。

公共語言運(yùn)行庫使用程序集來繼續(xù)致力于 DLL 沖突的徹底解決。

 

程序集解決方案:

為了解決版本控制問題以及導(dǎo)致 DLL 沖突的其余問題,運(yùn)行庫使用程序集來執(zhí)行以下功能:

·使開發(fā)人員能夠指定不同軟件組件之間的版本規(guī)則。

·提供強(qiáng)制實(shí)施版本控制規(guī)則的結(jié)構(gòu)。

·提供允許同時運(yùn)行多個版本的軟件組件(稱作并行執(zhí)行)的基本結(jié)構(gòu)。

 

3、程序集內(nèi)容

通常,靜態(tài)程序集可能由以下四個元素組成:

程序集清單,包含程序集元數(shù)據(jù)。
類型元數(shù)據(jù)。
實(shí)現(xiàn)這些類型的 Microsoft 中間語言 (MSIL) 代碼。
資源集。
只有程序集清單是必需的,但也需要類型或資源來向程序集提供任何有意義的功能。

程序集中的這些元素有分組幾種方法。您可以將所有元素分組到單個物理文件中,如下圖所示。

單文件程序集


或者,可以將一個程序集的元素包含在幾個文件中。這些文件可能是編譯代碼的模塊 (.netmodule)、資源(例如 .bmp 或 .jpg 文件)或應(yīng)用程序所需的其他文件。在您希望組合以不同語言編寫的模塊并優(yōu)化應(yīng)用程序的下載過程時,可創(chuàng)建一個多文件程序集,優(yōu)化下載過程的方法是將很少使用的類型放入只在需要時才下載的模塊中。

在下圖中,一個假想應(yīng)用程序的開發(fā)人員已選擇將一些實(shí)用工具代碼單獨(dú)放入另一個模塊中,同時在其原文件中保留一個較大的資源文件(在此例中為一個 .bmp 圖像)。.NET Framework 只在文件被引用時下載該文件;通過將很少引用的代碼保留在獨(dú)立于應(yīng)用程序的文件中來優(yōu)化代碼下載。

多文件程序集


說明:
 
構(gòu)成多文件程序集的那些文件實(shí)際上并非由文件系統(tǒng)來鏈接。它們而是通過程序集清單進(jìn)行鏈接,公共語言運(yùn)行庫將這些文件作為一個單元來管理。
 


在此插圖中,所有三個文件均屬于一個程序集,如 MyAssembly.dll 所包含的程序集清單文件中所述。對于該文件系統(tǒng),這三個文件是三個獨(dú)立的文件。請注意,文件 Util.netmodule 被編譯為一個模塊,因?yàn)樗话魏纬绦蚣畔?。在?chuàng)建了程序集后,該程序集清單就被添加到 MyAssembly.dll,指示程序集與 Util.net 模塊和 Graphic.bmp 的關(guān)系。

現(xiàn)在設(shè)計源代碼時,您會作出有關(guān)如何將應(yīng)用程序的功能劃分到一個或多個文件的明確的決定。在設(shè)計 .NET Framework 代碼時,您也將作出類似的決定,即如何將應(yīng)用程序的功能劃分到一個或多個程序集中。

 

4、程序集清單

每一程序集,無論是靜態(tài)的還是動態(tài)的,均包含描述該程序集中各元素彼此如何關(guān)聯(lián)的數(shù)據(jù)集合。程序集清單就包含這些程序集元數(shù)據(jù)。程序集清單包含指定該程序集的版本要求和安全標(biāo)識所需的所有元數(shù)據(jù),以及定義該程序集的范圍和解析對資源和類的引用所需的全部元數(shù)據(jù)。程序集清單可以存儲在具有 Microsoft 中間語言 (MSIL) 代碼的 PE 文件(.exe 或 .dll)中,也可存儲在只包含程序集清單信息的獨(dú)立 PE 文件中。

以下插圖顯示了清單的不同存儲方法。

程序集的類型


對于有一個關(guān)聯(lián)文件的程序集,該清單將被合并到 PE 文件中以構(gòu)成單文件程序集。您可以創(chuàng)建有獨(dú)立的清單文件,或清單被合并到同一多文件程序集中某一 PE 文件的多文件程序集。

每一程序集的清單均執(zhí)行以下功能:

·枚舉構(gòu)成該程序集的文件。

·控制對該程序集的類型和資源的引用如何映射到包含其聲明和實(shí)現(xiàn)的文件。

·枚舉該程序集所依賴的其他程序集。

·在程序集的使用者和程序集的實(shí)現(xiàn)詳細(xì)信息的使用者之間提供一定程度的間接性。

·呈現(xiàn)程序集自述。

 程序集清單內(nèi)容:

下表顯示了在程序集清單中包含的信息。前四項(程序集名稱、版本號、區(qū)域性和強(qiáng)名稱信息)構(gòu)成了程序集的標(biāo)識。

信息
 說明
 
程序集名稱
 指定程序集名稱的文本字符串。
 
版本號
 主版本號和次版本號,以及修訂號和內(nèi)部版本號。公共語言運(yùn)行庫使用這些編號來強(qiáng)制實(shí)施版本策略。
 
區(qū)域性
 有關(guān)該程序集支持的區(qū)域性或語言的信息。此信息只應(yīng)用于將一個程序集指定為包含特定區(qū)域性或特定語言信息的附屬程序集。(具有區(qū)域性信息的程序集被自動假定為附屬程序集。)
 
強(qiáng)名稱信息
 如果已經(jīng)為程序集提供了一個強(qiáng)名稱,則為來自發(fā)行者的公鑰。
 
程序集中所有文件的列表
 在程序集中包含的每一文件的散列及文件名。請注意,構(gòu)成程序集的所有文件所在的目錄必須是包含該程序集清單的文件所在的目錄。
 
類型引用信息
 運(yùn)行庫用來將類型引用映射到包含其聲明和實(shí)現(xiàn)的文件的信息。該信息用于從程序集導(dǎo)出的類型。
 
有關(guān)被引用程序集的信息
 該程序集靜態(tài)引用的其他程序集的列表。如果依賴的程序集具有強(qiáng)名稱,則每一引用均包括該依賴程序集的名稱、程序集元數(shù)據(jù)(版本、區(qū)域性、操作系統(tǒng)等)和公鑰。
 


通過在代碼中使用程序集屬性,您可以添加或更改程序集清單中的一些信息。您可以更改版本信息和信息性屬性,包括商標(biāo)、版權(quán)、產(chǎn)品、公司和信息性版本。

 

5、全局程序集緩存

安裝有公共語言運(yùn)行庫的每臺計算機(jī)都具有稱為全局程序集緩存的計算機(jī)范圍內(nèi)的代碼緩存。全局程序集緩存中存儲了專門指定給由計算機(jī)中若干應(yīng)用程序共享的程序集。

應(yīng)當(dāng)僅在需要時才將程序集安裝到全局程序集緩存中以進(jìn)行共享。一般原則是:程序集依賴項保持專用,并在應(yīng)用程序目錄中定位程序集,除非明確要求共享程序集。另外,不必為了使 COM 互操作或非托管代碼可以訪問程序集而將程序集安裝到全局程序集緩存。

說明:
 
在有些情況下,您顯然不希望將程序集安裝到全局程序集緩存中。如果您將組成應(yīng)用程序的某個程序集置于全局程序集緩存中,則將不再能夠通過使用 xcopy 命令復(fù)制應(yīng)用程序目錄來復(fù)制或安裝該應(yīng)用程序。您還必須在全局程序集緩存中移動該程序集。
 


有若干方法可以將程序集部署到全局程序集緩存中:

使用專用于全局程序集緩存的安裝程序。該方法是將程序集安裝到全局程序集緩存的首選方法。
使用 Windows 軟件開發(fā)工具包 (SDK) 提供的名為全局程序集緩存工具 (Gacutil.exe) 的開發(fā)工具。
使用 Windows 資源管理器將程序集拖到緩存中。
說明:
 
在部署方案中,應(yīng)該使用 Windows Installer 2.0 將程序集安裝到全局程序集緩存中。我們一般只在開發(fā)方案中使用 Windows 資源管理器或全局程序集緩存工具,這是因?yàn)樗鼈儾惶峁┦褂?Windows Installer 時可以提供的程序集引用計數(shù)功能和其他功能。
 


管理員通常使用訪問控制列表 (ACL) 來保護(hù) systemroot 目錄,以控制寫入和執(zhí)行訪問。因?yàn)槿殖绦蚣彺姘惭b在 systemroot 目錄的子目錄中,它繼承了該目錄的 ACL。建議只允許具有“管理員”權(quán)限的用戶從全局程序集緩存中刪除文件。

在全局程序集緩存中部署的程序集必須具有強(qiáng)名稱。將一個程序集添加到全局程序集緩存時,必須對構(gòu)成該程序集的所有文件執(zhí)行完整性檢查。緩存執(zhí)行這些完整性檢查以確保程序集未被篡改(例如,當(dāng)文件已更改但清單未反映此更改時)。

 

6、具有強(qiáng)名稱的程序集

      強(qiáng)名稱是由程序集的標(biāo)識加上公鑰和數(shù)字簽名組成的。其中,程序集的標(biāo)識包括簡單文本名稱、版本號和區(qū)域性信息(如果提供的話)。強(qiáng)名稱是使用相應(yīng)的私鑰,通過程序集文件(包含程序集清單的文件,并因而也包含構(gòu)成該程序集的所有文件的名稱和散列)生成的。Microsoft? Visual Studio? .NET 和 Windows 軟件開發(fā)工具包 (SDK) 中提供的其他開發(fā)工具能夠向一個程序集分配多個強(qiáng)名稱。強(qiáng)名稱相同的程序集應(yīng)該是相同的。

通過簽發(fā)具有強(qiáng)名稱的程序集,您可以確保名稱的全局唯一性。強(qiáng)名稱還特別滿足以下要求:

·強(qiáng)名稱依賴于唯一的密鑰對來確保名稱的唯一性。任何人都不會生成與您生成的相同的程序集名稱,因?yàn)橛靡粋€私鑰生成的程序集的名稱與用其他私鑰生成的程序集的名稱不相同。

·強(qiáng)名稱保護(hù)程序集的版本沿襲。強(qiáng)名稱可以確保沒有人能夠生成您的程序集的后續(xù)版本。用戶可以確信,他們所加載的程序集的版本出自創(chuàng)建該版本(應(yīng)用程序是用該版本生成的)的同一個發(fā)行者。

·強(qiáng)名稱提供可靠的完整性檢查。通過 .NET Framework 安全檢查后,即可確信程序集的內(nèi)容在生成后未被更改過。但請注意,強(qiáng)名稱中或強(qiáng)名稱本身并不暗含信任級別,例如由數(shù)字簽名和支持證書提供的信任。

在引用具有強(qiáng)名稱的程序集時,您應(yīng)該能夠從中受益,例如版本控制和命名保護(hù)。如果此具有強(qiáng)名稱的程序集以后引用了具有簡單名稱的程序集(后者沒有這些好處),則您將失去使用具有強(qiáng)名稱的程序集所帶來的好處,并依舊會產(chǎn)生 DLL 沖突。因此,具有強(qiáng)名稱的程序集只能引用其他具有強(qiáng)名稱的程序集。

 

7、程序集安全注意事項

      在您生成程序集時,您可以指定該程序集運(yùn)行所需的一組權(quán)限。是否將特定的權(quán)限授予程序集是基于證據(jù)的。

 

使用證據(jù)有兩種截然不同的方式:

·將輸入證據(jù)與加載程序所收集的證據(jù)合并,以創(chuàng)建用于策略決策的最終證據(jù)集。使用這種語義的方法包括 Assembly.Load、Assembly.LoadFrom 和 Activator.CreateInstance。

·原封不動地使用輸入證據(jù)作為用于策略決策的最終證據(jù)集。使用這種語義的方法包括 Assembly.Load(byte[]) 和 AppDomain.DefineDynamicAssembly()。

 

通過在將運(yùn)行程序集的計算機(jī)上設(shè)置安全策略,您可以授予一些可選的權(quán)限。如果您希望代碼可以處理所有潛在的安全異常,可以執(zhí)行以下操作之一:

·為您的代碼必須具有的所有權(quán)限插入權(quán)限請求,并預(yù)先處理在未授予權(quán)限時發(fā)生的加載時錯誤。

·不要使用權(quán)限請求來獲取您的代碼可能需要的權(quán)限,但一定要準(zhǔn)備處理在未授予權(quán)限時發(fā)生的安全異常。

 

說明:

安全性是一個較為復(fù)雜的領(lǐng)域,您將要作出很多選擇。

 

在加載時,程序集的證據(jù)用作安全策略的輸入。安全策略是由企業(yè)和計算機(jī)的管理員以及用戶策略設(shè)置建立的,它在執(zhí)行時確定向所有托管代碼授予的權(quán)限組。可以為該程序集(如果該程序集具有簽名工具生成的簽名)的發(fā)行者建立安全策略,或者為該程序集的下載網(wǎng)站和區(qū)域(就 Internet Explorer 而言)建立安全策略,也可以為該程序集的強(qiáng)名稱建立該策略。例如,一臺計算機(jī)的管理員可以建立這樣一種安全策略:它允許從某一網(wǎng)站下載由指定軟件公司簽發(fā)用以訪問計算機(jī)上的數(shù)據(jù)庫的所有代碼,但不授予對該計算機(jī)磁盤的寫訪問權(quán)。

 

強(qiáng)名稱程序集和簽名工具

可以用兩種不同但相互補(bǔ)充的方式對程序集進(jìn)行簽名:使用強(qiáng)名稱或使用 .NET Framework 1.0 和 1.1 版中的 文件簽名工具 (Signcode.exe) 或 .NET Framework 更高版本中的 簽名工具 (SignTool.exe)。使用強(qiáng)名稱對程序集進(jìn)行簽名將向包含程序集清單的文件添加公鑰加密。強(qiáng)名稱簽名幫助驗(yàn)證名稱的唯一性,避免名稱欺騙,并在解析引用時向調(diào)用方提供某標(biāo)識。

但是,任何信任級別都不會與一個強(qiáng)名稱關(guān)聯(lián),這樣 文件簽名工具 (Signcode.exe) 和 簽名工具 (SignTool.exe) 就變得十分重要。這兩個簽名工具要求發(fā)行者向第三方證書頒發(fā)機(jī)構(gòu)證實(shí)其標(biāo)識并獲取證書。然后此證書將嵌入到您的文件中,并且管理員能夠使用該證書來決定是否相信這些代碼的真實(shí)性。

您可以將強(qiáng)名稱和使用 文件簽名工具 (Signcode.exe) 或 簽名工具 (SignTool.exe) 創(chuàng)建的數(shù)字簽名一起提供給程序集,或者您可以單獨(dú)使用其中之一。這兩個簽名工具一次只能對一個文件進(jìn)行簽名,對于多文件程序集,您可以對包含程序集清單的文件進(jìn)行簽名。強(qiáng)名稱存儲在包含程序集清單的文件中,但使用 文件簽名工具 (Signcode.exe) 或 簽名工具 (SignTool.exe) 創(chuàng)建的簽名存儲在該程序集清單所在的可移植可執(zhí)行 (PE) 文件中保留的槽中。當(dāng)您已經(jīng)具有依賴于 文件簽名工具 (Signcode.exe) 或 簽名工具 (SignTool.exe) 生成的簽名的信任層次結(jié)構(gòu)或者當(dāng)您的策略只使用密鑰部分并且不檢查信任鏈時,就可以使用通過 文件簽名工具 (Signcode.exe) 或簽名工具 (SignTool.exe) 對程序集進(jìn)行的簽名(帶或不帶強(qiáng)名稱)。

 

說明:

在一個程序集上同時使用強(qiáng)名稱和簽名工具簽名時,必須首先分配強(qiáng)名稱。

 

公共語言運(yùn)行庫還將執(zhí)行哈希驗(yàn)證;程序集清單包含構(gòu)成該程序集的所有文件的列表,包括當(dāng)生成清單時存在的每一文件的散列。在加載每一文件時,其內(nèi)容被散列化并與清單中存儲的哈希值進(jìn)行比較。 如果兩個哈希值不匹配,則無法加載該程序集。

因?yàn)閺?qiáng)名稱和使用 文件簽名工具 (Signcode.exe) 或 簽名工具 (SignTool.exe) 進(jìn)行簽名確保了完整性,因此您可以將代碼訪問安全策略建立在這兩種形式的程序集證據(jù)的基礎(chǔ)上。強(qiáng)名稱和使用 文件簽名工具 (Signcode.exe) 或 簽名工具 (SignTool.exe) 進(jìn)行簽名通過數(shù)字簽名和證書來確保完整性。上面提到的所有技術(shù)(哈希驗(yàn)證、強(qiáng)名稱和使用 文件簽名工具 (Signcode.exe) 或 簽名工具 (SignTool.exe) 進(jìn)行簽名)共同作用,可以確保程序集沒有做過任何方式的改動。

 

8、程序集版本控制

使用公共語言運(yùn)行庫的程序集的所有版本控制都在程序集級別上進(jìn)行。一個程序集的特定版本和依賴程序集的版本在該程序集的清單中記錄下來。除非被配置文件(應(yīng)用程序配置文件、發(fā)行者策略文件和計算機(jī)的管理員配置文件)中的顯式版本策略重寫,否則運(yùn)行庫的默認(rèn)版本策略是,應(yīng)用程序只與它們生成和測試時所用的程序集版本一起運(yùn)行。

說明:

      僅對具有強(qiáng)名稱的程序集進(jìn)行版本控制。

運(yùn)行庫執(zhí)行以下幾步來解析程序集綁定請求:

1.     檢查原程序集引用,以確定該程序集的版本是否被綁定。

2.     檢查所有適用的配置文件以應(yīng)用版本策略。

3.     通過原程序集引用和配置文件中指定的任何重定向來確定正確的程序集,并且確定應(yīng)綁定到調(diào)用程序集的版本。

4.     檢查全局程序集緩存和在配置文件中指定的基本代碼,然后使用在運(yùn)行庫如何定位程序集中解釋的探測規(guī)則檢查該應(yīng)用程序的目錄和子目錄。

下圖說明了這些步驟。

解析程序集綁定請求

 


 版本信息

每一程序集都用兩種截然不同的方法來表示版本信息:

程序集的版本號,該版本號與程序集名稱及區(qū)域性信息都是程序集標(biāo)識的組成部分。該號碼將由運(yùn)行庫用來強(qiáng)制實(shí)施版本策略,它在運(yùn)行時的類型解析進(jìn)程中起著重要的作用。
信息性版本,這是一個字符串,表示僅為提醒的目的而包括的附加版本信息。
程序集版本號

每一程序集都有一個版本號作為其標(biāo)識的一部分。因此,如果兩個程序集具有不同的版本號,運(yùn)行庫就會將它們視作完全不同的程序集。此版本號實(shí)際表示為具有以下格式的四部分號碼:

<major version>.<minor version>.<build number>.<revision>

例如,版本 1.5.1254.0 中的 1 表示主版本,5 表示次版本,1254 表示內(nèi)部版本號,而 0 則表示修訂號。

版本號與其他標(biāo)識信息(包括程序集名稱和公鑰,以及與該應(yīng)用程序所連接的其他程序集的關(guān)系和標(biāo)識有關(guān)的信息)一起存儲在程序集清單中。

在生成程序集時,開發(fā)工具將把每一個被引用程序集的依賴項信息記錄在程序集清單中。運(yùn)行庫將這些版本號與管理員、應(yīng)用程序或發(fā)行者設(shè)置的配置信息結(jié)合使用,以加載被引用程序集的正確版本。

為進(jìn)行版本控制,運(yùn)行庫會區(qū)分常規(guī)程序集和具有強(qiáng)名稱的程序集。只對具有強(qiáng)名稱的程序集執(zhí)行版本檢查。

程序集信息性版本

信息性版本是一個字符串,它僅出于提醒的目的將附加的版本信息附加到一個程序集;此信息不在運(yùn)行時使用?;谖谋镜男畔⑿园姹鞠喈?dāng)于產(chǎn)品的營銷廣告、包裝或產(chǎn)品名稱,不被運(yùn)行庫使用。例如,信息性版本可以是“公共語言運(yùn)行庫版本 1.0”或“NET Control SP 2”。在 Microsoft Windows 中的文件屬性對話框的“版本”選項卡上,此信息顯示在“產(chǎn)品版本”項中。

說明:

雖然可以指定任意文本,但是如果字符串的格式不是程序集版本號使用的格式,或者雖然是這種格式但包含通配符,則在編譯時會顯示一條警告消息。此警告無礙

信息性版本用自定義屬性 System.Reflection..::.AssemblyInformationalVersionAttribute 表示。有關(guān)信息性版本屬性的更多信息,請參見設(shè)置程序集屬性。

 

9、程序集位置

      對于大多數(shù) .NET Framework 應(yīng)用程序而言,您可以在以下位置找到構(gòu)成該應(yīng)用程序的程序集,這些位置包括:該應(yīng)用程序的目錄中,該應(yīng)用程序目錄的子目錄中,或全局程序集緩存中(如果該程序集是共享的話)??梢酝ㄟ^在配置文件中使用 <codeBase> 元素重寫公共語言運(yùn)行庫查找某一程序集的位置。如果該程序集沒有強(qiáng)名稱,則使用 <codeBase> 元素指定的位置將被限制在應(yīng)用程序目錄或子目錄中。如果程序集具有強(qiáng)名稱,則 <codeBase> 元素 能夠指定計算機(jī)或網(wǎng)絡(luò)上的任意位置。

當(dāng)在使用非托管代碼或 COM 互操作應(yīng)用程序的過程中查找程序集的位置時,類似的規(guī)則同樣適用:如果該程序集將由多個應(yīng)用程序共享,則此程序集應(yīng)被安裝到全局程序集緩存中。和非托管代碼一起使用的程序集必須作為類型庫導(dǎo)出并注冊。由 COM 互操作 使用的程序集必須在目錄中進(jìn)行注冊,盡管有些情況下會自動進(jìn)行此注冊。

 

10、程序集和并行執(zhí)行

      并行執(zhí)行是在同一臺計算機(jī)上存儲和執(zhí)行應(yīng)用程序或組件的多個版本的能力。這意味著在同一臺計算機(jī)上可以同時有運(yùn)行庫的多個版本,并且可以有使用其中某個運(yùn)行庫版本的應(yīng)用程序和組件的多個版本。并行執(zhí)行使您能夠更多地控制應(yīng)用程序綁定到的組件版本和應(yīng)用程序使用的運(yùn)行庫版本。

支持并行存儲和執(zhí)行同一程序集的不同版本是強(qiáng)命名中不可缺少的部分,這種支持內(nèi)置于運(yùn)行庫基礎(chǔ)結(jié)構(gòu)中。因?yàn)閺?qiáng)名稱程序集的版本號是其標(biāo)識的一部分,所以運(yùn)行庫能夠在全局程序集緩存中存儲同一程序集的多個版本,并且在運(yùn)行時加載這些程序集。

盡管運(yùn)行庫使您能夠創(chuàng)建并行應(yīng)用程序,但并行執(zhí)行并不是自動進(jìn)行的。


本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/dodream/archive/2009/10/20/4704050.aspx

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
(1)程序集基礎(chǔ)知識
應(yīng)用程序配置和動態(tài)加載1----程序集
用.Net寫好的DLL如何能讓非.Net的程序使用呢?(如VB6)
VC分發(fā)包版本問題
C#編程技巧:獲取當(dāng)前應(yīng)用程序的路徑
C#學(xué)習(xí)筆記(二)——第一個應(yīng)用程序
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服