C#學習筆記1——程式集

來源:互聯網
上載者:User
文章目錄
  • 在 VisualStudio 中建立程式集和friend 組件
  • 在 VisualStudio 中建立簽名的程式集和friend 組件

一、程式集概念、特性

程式集構成了基於 .NET 的應用程式的部署、版本控制、重用、啟用範圍和安全許可權的基本單元。程式集以可執行 (.exe) 檔案或動態連結程式庫 (.dll) 檔案的形式出現,是 .NET Framework 的產生塊。它們向通用語言執行平台提供瞭解類型實現所需要的資訊。可以將程式集看成是構成邏輯功能單元並為一起工作而產生的類型和資源的集合。

程式集可以包含一個或多個模組。例如,計劃較大的項目時,可以讓幾個各個開發人員負責單獨的模組,並通過組合所有這些模組來建立單個程式集。

程式集具有以下特點:

程式集作為 .exe 或 .DLL 檔案實現。

通過將程式集放在全域組件快取中,可在多個應用程式之間共用組件。在將程式集包含在全域組件快取之前,必須對程式集進行強命名。有關更多資訊,請參見具有強式名稱的程式集。

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

可以使用反射以編程方式擷取關於程式集的資訊。有關更多資訊,請參見反射。

如果載入程式集的目的只是對其進行檢查,應使用諸如ReflectionOnlyLoadFrom的方法。

資訊清單

每個程式集中都有一個“資訊清單”。類似於目錄,資訊清單包含以下內容:

1、程式集的標識(其名稱和版本)。

2、檔案表,描述組成程式集的所有其他檔案,例如包括建立的.exe 或 .DLL 檔案所依賴的任何其他程式集,甚至包括位元影像檔案或讀我檔案。

3、“程式集引用列表”是所有外部依賴項的一個列表,這些外部依賴項就是一些 .dll 或已由其他人建立而您的應用程式所需的其他檔案。程式集引用同時包含對全域對象和私人對象的引用。全域對象駐留在全域組件快取中(可供其他應用程式使用的地區,有些類似於 System32 目錄)。私人對象必須在應用程式安裝目錄的同一級(或下一級)目錄中。

由於程式集包含有關內容、版本控制和依賴項的資訊,因此用 Visual Basic 和 C# 建立的應用程式不依賴註冊表值就可正常運行。程式集減少了 .dll 衝突,使應用程式更加可靠和更易於部署。許多情況下,只需將基於 .NET 應用程式的檔案複製到目標電腦就可以安裝該應用程式。

 

二、程式集分類

1、私用組件

私用組件是最簡單的一種程式集類型。私用組件一般附帶在某些軟體上,且只能用於該軟體中。附帶私用組件的常見情況是,以可執行檔或許多庫的方式提供應用程式,這些庫包含的代碼只能用於該應用程式。

系統可以保證私用組件不被其他軟體使用,因為應用程式只能載入位於主執行檔案所在檔案夾或其子檔案夾中的程式集。

使用者一般會希望把商用軟體安裝在它自己的目錄下,這樣軟體包沒有覆蓋、修改或載入另一個軟體包的私用組件的風險。私用組件只能用於自己的軟體包,這樣,使用者對什麼軟體使用它們就有了更多的控制。因此,不需要採取安全措施,因為這沒有其他商用軟體用某個新版本的程式集覆蓋原來的私用組件的風險(但軟體是專門執行懷有惡意的損害性操作的情況除外)。名稱也不會有衝突。如果私用組件中的類正巧與另一個人的私用組件中的類同名,是不會有問題的,因為給定的應用程式只能使用私用組件的名稱。

因為私用組件完全是自含式的,所以安裝它的過程就很簡單。只需把相應的檔案放在檔案系統的對應檔案夾中即可(不需要登錄機碼),這個過程稱為“0影響(xcopy)安裝”。

2、共用組件

共用組件是其他應用程式可以使用的公用庫。因為其他軟體可以訪問共用組件,所以需要採取一定的保護措施來防止以下風險:

● 名稱衝突,另一個公司的共用組件執行的類型與自己的共用組件中的類型同名。因為客戶機代碼理論上可以同時訪問這些程式集,所以這是一個嚴重的問題。

● 程式集被同一個程式集的不同版本覆蓋——新版本與某些已有的客戶機代碼不相容。

這些問題的解決方案是把共用組件放在檔案系統的一個特定的子目錄樹中,稱為全域程式集快取(GAC)。與私用組件不同,不能簡單地把共用組件複製到對應的檔案夾中,而需要專門安裝到快取中,這個過程可以用許多.NET工具來完成,其中包含對程式集的檢查、在程式集快取中設定一個小的資料夾階層,以確保程式集的完整性。

為了避免名稱衝突,共用組件應根據私人祕密金鑰加密法指定一個名稱(私用組件只需要指定與其主檔案名相同的名稱即可)。該名稱稱為強名(strongname),並保證其惟一性,它必須由要引用共用組件的應用程式來引用。

與覆蓋程式集相關的問題,可以通過在資訊清單中指定版本資訊來解決,也可以通過同時安裝來解決。

一個強命名程式集包含四個唯一標誌程式集的特性:檔案名稱(沒有副檔名),版本號碼,語言文化資訊(如果有的話),公有密鑰。

這些資訊儲存在程式集的清單(manifest)中。清單包含了程式集的中繼資料,並嵌入在程式集的某個檔案中。

下面的字串標識了四個不同的組件檔:

“MyType, Version=1.0.1.0,
Culture=neutral, PublicKeyToken=bf5779af662fc055”

“MyType, Version=1.0.1.0,
Culture=en-us, PublicKeyToken=bf5779af662fc055”

“MyType, Version=1.0.2.0,
Culture=neturl, PublicKeyToken=bf5779af662fc055”

“MyType, Version=1.0.2.0,
Culture=neutral, PublicKeyToken=dbe4120289f9fd8a

 

建立和使用共用組件有一些特殊的步驟,

1.     使用sn.exe建立加密檔案,sn.exe -k test.snk

2.     在公用程式集的原始碼中加入屬性,[assembly:AssemblyKeyFileAttribute("test.snk")],習慣放在所有using的後面。或者通過projectproperties->Signing->Sign the assembly來指定加密檔案

3.     使用gacutil -i test.dll安裝共用組件,安裝後在C:/WINDOWS/assembly目錄下將看到test檔案

 

 

三、friend 組件

“friend 組件”是一種能夠訪問其他程式集的Friend(Visual Basic) 或 internal (C#) 類型和成員的程式集。如果將程式集指定為friend 組件,則不再需要將類型和成員標記為公用,以使其他程式集可以訪問它們。在以下情況下,使用friend 組件尤其方便:

·        在單元測試中,測試代碼在另一個程式集中運行,但需要訪問正在測試的標記為Friend (Visual Basic) 或 internal (C#) 的程式集中的成員。

·        您正在開發類庫,庫的附加部分包含在單獨的程式集中,但需要訪問標記為Friend (Visual Basic) 或 internal (C#) 的現有程式集中的成員。

如何:建立未簽名friend 組件

在 VisualStudio 中建立程式集和friend 組件

1.   開啟 VisualStudio 命令提示。

2.   建立一個名為 friend_signed_A. 的 Visual Basic 或 C# 檔案,其中包含以下代碼。該代碼使用 InternalsVisibleToAttribute特性將 friend_signed_B 聲明為friend 組件。

// friend_unsigned_A.cs
// Compile with: 
// csc /target:library friend_unsigned_A.cs
using System.Runtime.CompilerServices;
using System;
 
[assembly: InternalsVisibleTo("friend_unsigned_B")]
 
// Type is 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");
    }
}

3.   使用以下命令編譯friend_signed_A 並為其簽名。

csc /target:library friend_unsigned_A.cs

4.   建立一個名為 friend_unsigned_B 的 Visual Basic 或 C# 檔案,其中包含以下代碼。由於 friend_unsigned_A 將 friend_unsigned_B 指定為friend 組件,因此friend_unsigned_B 中的代碼可以訪問 friend_unsigned_A 中的 Friend (Visual Basic) 或 internal (C#) 類型和成員。

// friend_unsigned_B.cs
// Compile with: 
// csc /r:friend_unsigned_A.dll /out:friend_unsigned_B.exe friend_unsigned_B.cs
public class Program
{
    static void Main()
    {
        // Access an internal type.
        Class1 inst1 = new Class1();
        inst1.Test();
 
        Class2 inst2 = new Class2();
        // Access an internal member of a public type.
        inst2.Test();
 
        System.Console.ReadLine();
    }
}
 

5.   使用以下命令編譯friend_signed_B。

csc /r:friend_unsigned_A.dll /out:friend_unsigned_B.exe friend_unsigned_B.cs

編譯器產生的程式集的名稱必須與傳遞給 InternalsVisibleToAttribute特性的friend 組件名稱匹配。可以使用 /out 編譯器選項顯式設定該程式集。

在 C# 中,您必須使用/out 編譯器選項顯式指定輸出程式集(.exe 或 .dll)的名稱。在 Visual Basic 中,這是可選的。

6.   運行 friend_signed_B.exe檔案。

程式將列印兩個字串:“Class1.Test”和“Class2.Test”。

安全性

InternalsVisibleToAttribute特性和 StrongNameIdentityPermission類之間存在相似性。主要的差異在於:StrongNameIdentityPermission可以要求具有安全許可權才能運行特定的一段代碼,而 InternalsVisibleToAttribute特性則控制 Friend (Visual Basic) 或 internal (C#) 類型和成員的可見度。

如何:建立簽名的friend 組件

在 VisualStudio 中建立簽名的程式集和friend 組件

1.   開啟 VisualStudio 命令提示。

2.   使用強式名稱工具,通過以下命令序列產生 keyfile 並顯示其公開金鑰。有關更多資訊,請參見Sn.exe(強式名稱工具)。

1.   產生此樣本的強式名稱密鑰,並將其儲存在 FriendAssemblies.snk 檔案中:

sn -kFriendAssemblies.snk

2.   從FriendAssemblies.snk 檔案中提取公開金鑰,將其放入FriendAssemblies.publickey 中:

sn -pFriendAssemblies.snk FriendAssemblies.publickey

3.   顯示儲存在FriendAssemblies.publickey 檔案中的公開金鑰:

sn -tpFriendAssemblies.publickey

3.   建立一個名為 friend_signed_A 的 Visual Basic 或 C#檔案,其中包含以下代碼。該代碼使用 InternalsVisibleToAttribute特性將 friend_signed_B 聲明為friend 組件。

強式名稱工具在每次運行時產生新的公開金鑰。因此,必須將以下代碼中的公開金鑰替換為剛產生的公開金鑰,如下例所示。

// friend_signed_A.cs
// Compile with: 
// csc /target:library /keyfile:FriendAssemblies.snk friend_signed_A.cs
using System.Runtime.CompilerServices;
 
[assembly: InternalsVisibleTo("friend_signed_B, PublicKey=0024000004800000940000000602000000240000525341310004000001000100e3aedce99b7e10823920206f8e46cd5558b4ec7345bd1a5b201ffe71660625dcb8f9a08687d881c8f65a0dcf042f81475d2e88f3e3e273c8311ee40f952db306c02fbfc5d8bc6ee1e924e6ec8fe8c01932e0648a0d3e5695134af3bb7fab370d3012d083fa6b83179dd3d031053f72fc1f7da8459140b0af5afc4d2804deccb6")]
class Class1
{
    public void Test()
    {
        System.Console.WriteLine("Class1.Test");
        System.Console.ReadLine();
    }
}
 
 

4.   使用以下命令編譯friend_signed_A 並為其簽名。

csc /target:library /keyfile:FriendAssemblies.snk friend_signed_A.cs

5.   建立一個名為 friend_signed_B 的 Visual Basic 或 C#檔案,並包含以下代碼。由於 friend_signed_A 將friend_signed_B 指定為friend 組件,因此 friend_signed_B 中的代碼可以訪問 friend_signed_A 中的 Friend (VisualBasic) 或 internal (C#) 類型和成員。檔案包含以下代碼。

// friend_signed_B.cs
// Compile with: 
// csc /keyfile:FriendAssemblies.snk /r:friend_signed_A.dll /out:friend_signed_B.exe friend_signed_B.cs
public class Program
{
    static void Main()
    {
        Class1 inst = new Class1();
        inst.Test();
    }
}
 
 

6.   使用以下命令編譯friend_signed_B 並為其簽名。

不支援該語言或沒有可用的程式碼範例。
csc /keyfile:FriendAssemblies.snk /r:friend_signed_A.dll /out:friend_signed_B.exe friend_signed_B.cs

編譯器產生的程式集的名稱必須與傳遞給 InternalsVisibleToAttribute特性的元程式集的名稱匹配。可以使用/out 編譯器選項顯式設定該程式集。

在 C# 中,您必須使用/out 編譯器選項顯式指定輸出程式集(.exe 或 .dll)的名稱。在 Visual Basic 中,這是可選的。

7.   運行friend_signed_B.exe 檔。

程式將列印字串“Class1.Test”。

四、如何把共用組件添加到引用

1. 如何建立強名程式集

可以用VS來產生公開金鑰金鑰組檔案, Project Properties à Signing

2. 如何查看public key token

可以用命令   sn–T [assembly]

3. 安裝共用組件

只有強名程式集才可以安裝到Gac中。可以用命令

gacutil /i[assembly]

    

4. 卸載共用組件

可以在C:/Windows/assembly目錄下,找到要卸載的程式集,按右鍵,然後選擇Uninstall.

5. 如何對共用組件在VS中添加引用

首先運行Start > Run >"C:/windows/assembly ".

選擇你要找的程式集的檔案夾,然後進入該檔案夾,再選擇正確的版本的檔案夾。

找到你要的程式集後,可先將其臨時拷貝到一個位置,再把這個拷貝程式集添加到引用中,然後便可以刪除這個暫存程序集拷貝,因為VS會自動在GAC中搜尋該程式集。

 

五、如何:確定檔案是否為程式集

如何手動確定一個檔案是否為程式集

1、啟動Ildasm.exe(MSIL 反組譯工具)。

載入希望測試的檔案。

如果 ILDASM 報告該檔案不是可遷移的可執行 (PE) 檔案,則它不是程式集。有關更多資訊,請參見主題 如何:查看程式集內容。

2、如何以編程方式確定一個檔案是否為程式集

調用 GetAssemblyName方法,並向其傳遞正在測試的檔案的完整檔案路徑和名稱。

如果引發 BadImageFormatException異常,則該檔案不是程式集。

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.