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

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
C#程序集(assembly)(精)

程序集

===============================================================================================
     ----------------------------------------------------------------------1 什么是程序集? ----------------------------------------------------------------------
DLL的版本問題,程序不知道到底該使用哪個DLL版本,從而產(chǎn)生中斷。
DLL-Hell----〉與DLL相關(guān)的問題
.NET對DLL-Hell及其所有問題的答案是使用程序集
程序集-是自我描述的安裝單元,由一個或多個文件組成,一個程序集可以是一個包括元數(shù)據(jù)的DLL或EXE,也可以由多個文件組成。
另一優(yōu)點是可以使私有或共享的。
私有程序集和共享程序集有很大的區(qū)別
版本沖突問題必須在開發(fā)階段解決
程序集的特性: 1 程序集是自我描述的;
      2 版本的互相依賴性在程序集的清單中進(jìn)行了記錄
      3 程序集可以進(jìn)行并行加載 ,同一個DLL的不同版本可以在同一個系統(tǒng)上同時使用
      4 應(yīng)用程序使用應(yīng)用程序域來確保其獨立性(Application Domain)
      5 安裝非 常簡單,只要復(fù)制一個程序集中的所有文件,一個xcopy命令就夠了--無干涉部署(No-touch Deployment)

應(yīng)用程序集和應(yīng)用程序域

      -----------------------   |     ----------------------------
       進(jìn)程一       進(jìn)程二
____________   |   ____________
應(yīng)用程序域A
應(yīng)用程序域B   |
      ......
____________   |   ____________
    -------------------------     ----------------------------
進(jìn)程之間有邊界,應(yīng)用程序域存在于某個進(jìn)程中,之間也有邊界,處在不同應(yīng)用程序域中的應(yīng)用程序不能互相訪問
應(yīng)用程序域可以互相包含

------------------------------------------
======================
進(jìn)程〉應(yīng)用程序域〉程序集〉對象
======================
------------------------------------------
應(yīng)用程序域之間可以通信,或使用代理
AppDomain類用于創(chuàng)建和中斷應(yīng)用程序域,加載和卸載程序集和類,枚舉域中的程序集和線程
例如: 1--創(chuàng)建一個控制臺應(yīng)用程序AssemblyA
2--第二個應(yīng)用程序DomainTest加載AssemblyA.exe程序集
/////////////////////////////////////////////////////////////////////////////////////////
using System;
namespace Wrox.ProCSharp.Assemblies.AppDomains
{
   class Class1
   {
    public Class1(int val1,int val2)
    {//構(gòu)造函數(shù),具有兩個參數(shù),以了解如何創(chuàng)建AppDomain類的實例
     Console.WriteLine("Constructor with the values {0},{1}"+
       "in domain {2} called",val1,val2,
       AppDomain.CurrentDomain.FriendlyName);
    }
    [STAThread]
    static void Main(string[] args)
    {//在Main中,從而知道什么時候調(diào)用Console.WriteLine
     Console.WriteLine("Main in domain {0} called",
       AppDomain.CurrentDomain.FriendlyName);
    }
   }
}
//////// /////////////////////////////////////////////////////////////////////////////////
using System;
namespace Wrox.ProCShap.Assemblies.AppDomains
{
   class Test
   {
    [STAThread]
    static void Main(string[] args)
    {
     AppDomain currentDomain = AppDomain.CurrentDomain;
     Console.WriteLine(currentDomain.FriendlyName);
     //使用AppDomain類的FriendlyName屬性顯示當(dāng)前域的名稱

     ////FLAG////
     AppDomain.secondDomain = AppDomain.CreateDomain("New AppDomain");
     //創(chuàng)建一個新的應(yīng)用程序域New AppDomain

     secondDomain.ExecuteAssembly("AssemblyA.exe");
     //把程序集AssemblyA加載到新域中,通過調(diào)用ExecuteAssembly來調(diào)用Main()方法
    }
   }
}

在啟動DomainTest.exe前,必須把程序集AssemblyA.exe復(fù)制到DomainTest.exe所在的目錄下,這樣程序才能找到
這個程序集,不能添加AssemblyA.exe程序集的引用,因為在VS.NET中,只能給以DLL格式存儲的程序集添加引用,不支持
EXE格式,但是EXE格式的程序集可以在命令行上執(zhí)行,如果找不到這個程序集就會拋出System.IO.FileNotFoundExection異常
結(jié)果:Main in domain New AppDomain called

在上面第二個程序表明的FLAG處可以改為:再創(chuàng)建一個實例,用于替代Main()方法
/////////////////////////////////////////////////////////////////////////////////////////
AppDomain secondDomain = AppDomain.CreateDomain("New AppDomain");

secondDomain.CreateInstance("AssemblyA" ,"Wrox.ProCShap.Assemblies.AppDomains.Class1",
     true,System.Reflection.BindingFlags.CreateInstance,null,new object[]{7,3}
     null,null,null);
/////////////////////////////////////////////////////////////////////////////////////////
//1-程序集名;2-應(yīng)實例化的類;3-true表示不區(qū)分大小寫;4-邦定標(biāo)志枚舉值,指定應(yīng)調(diào)用的構(gòu)造函數(shù);
得到的輸出為:Constructor with the values 7,3 in domain New AppDomain called


在運行期間主應(yīng)用程序域會自動創(chuàng)建,
ASP.NET為每個運行在WEB服務(wù)器上的Web應(yīng)用程序創(chuàng)建一個應(yīng)用程序域,
Internet Explorer創(chuàng)建運行托管控件的應(yīng)用程序域,
卸載應(yīng)用程序域只能通過中斷應(yīng)用程序域來進(jìn)行


     ----------------------------------------------------------------------2 程序集的結(jié)構(gòu) ----------------------------------------------------------------------
程序集由=描述它的元數(shù)據(jù)(程序集元數(shù)據(jù))+描述導(dǎo)出類型和方法的類型元數(shù)據(jù)+MSIL代碼+資源
存在于一個文件中或分布在多個文件中
例如: 1 程序集由一個文件組成:Component.dll
2 Component.dll=描述它的元數(shù)據(jù)+描述導(dǎo)出類型和方法的類型元數(shù)據(jù)+MSIL代碼,
   資源不在其中
   這個程序集使用了一個圖:Pictrue.jpeg,該圖沒有嵌入在dll中,而是在程序集的元數(shù)據(jù)中引用
   程序集的原數(shù)據(jù)還引用了一個模塊:Util.netmodule,該模塊只包含一個類的類型元數(shù)據(jù)和MSIL代碼
   不包含程序集的元數(shù)據(jù),所以這個模塊沒有版本信息,也不能單獨安裝
   這3個文件構(gòu)成了程序集,這個程序集是一個安裝單元,還可以在另外一個文件中放置程序集清單
    Component.dll   Util.netmodule
   ________________________ ____________
Picture.jpeg<------- 程序集元數(shù)據(jù)   -------〉 類型元數(shù)據(jù)
__________     -------〉 IL代碼
資源   類型元數(shù)據(jù)   
   IL代碼

程序集的清單
元數(shù)據(jù)的一部分,描述了程序集和引用它所需的所有信息,并列出,了所有的依賴關(guān)系
清單=標(biāo)識(名稱,版本,文化,公鑰)+屬于該程序集的一個文件列表+
引用程序集的列表+一組許可請求--運行的許可證+
導(dǎo)出的類型(當(dāng)它們在一個模塊中定義,該模塊在程序集中引用,否則不屬于清單)

---------------------------------------------
======================
命名空間,程序集和組件
1 命名空間完全獨立于程序集
2 一個程序集中可以有不同的命名空間
3 一個命名空間也可以分布在多個程序集中
4 命名空間只是類名的一種擴(kuò)展,它屬于類名的范疇
======================
---------------------------------------------

======================
私有程序集和共享程序集
在使用共享程序集時,程序集必須是唯一的,名稱唯一(強名),該名稱的一部分是一個強制的版本號,如第三方控件
======================
======================
查看程序集
命令行工具:ILDASM

FILE-->OPEN-->打開程序集
======================
======================
構(gòu)建程序集
1-可以創(chuàng)建模塊:csc /target:module hello.cs 模塊是一個沒有程序集特性的DLL,可以添加到程序集中
創(chuàng)建了hello.netmodule
2-生成一個程序集B.DLL ,它包含模塊A.netmodule: csc /target:library /addmodule:A.netmodule /out:B.dll
3-模塊的作用1是可以更快的啟動程序集,因為并不是所有類都在一個文件中
   模塊只在需要時加載
2是是否需要使用多種編程語言來創(chuàng)建一個程序集:一個模塊用VB.net,一個模塊用C#,這兩個模塊都包含在一個程序集中
4-使用VS創(chuàng)建程序集
VS2003不支持直接創(chuàng)建模塊
創(chuàng)建一個項目時,系統(tǒng)自動生成源文件AssemblyInfo.cs,在該文件中可以使用一般的源代碼編輯器配置程序集的屬性
[assembly]和[module]是程序集的全局屬性

System.Reflection命名空間中的類:
AssemblyCompany     ---指定公司名
AssemblyConfiguration    --指定建立信息,例如零售或調(diào)試信息
AssemblyCopyright/Assembly Trademark --包含版權(quán)和商標(biāo)信息
AssemblyDefaultAlias    --如果程序集名稱不容易理解,如動態(tài)創(chuàng)建程序集名稱時的GUID,就可以使用該屬性,指定一個別名
AssemblyDescription    --描述程序集或產(chǎn)品,如果查看可執(zhí)行文件的屬性,這個值就會顯示為Comments
AssemblyProduct     --指定了屬于該程序集的產(chǎn)品名稱
AssemblyInfomationalVersion    --在引用程序集時,這個屬性不用于版本檢查,僅用于版本信息,非常適用于指定使用多個程序集的應(yīng)用程序的版本,打開可執(zhí)行程序的屬性,這個值就顯示為Product Version
AssemblyTitle     --是程序集的描述性名稱,可以包括空格,查看屬性時顯示為Description

System.Runtime.CompilerServices命名空間中的類:
AssemblyCulture      --程序集的文化背景,如en-US
AssemblyDelaySign/AssemblyKeyFile/AssemblyKeyName --用于創(chuàng)建共享程序集的強名
AssemblyVersion      --指定程序集的版本號,版本問題在共享程序集中具有非常重要的地位
======================

======================
跨語言支持
.NET 使用通用類型系統(tǒng)Common Type System-CTS-定義了如何在.net中定義值類型和引用類型,以及這些類型的內(nèi)存布局
但CTS沒有確保在任何語言中定義的類型都可以用于其它語言。
這應(yīng)是公共語言規(guī)范Common Language Specification-CLS 的任務(wù)。
CLS定義了.net語言必須支持的最低要求
======================

CTS=common type system=通用類型系統(tǒng)
CLS=common language specification=公共語言規(guī)范
======================
例如:
**********************************************************************************
Visual C++編寫的基類HelloMCPP/   繼承于HelloMCPP的類HelloVB/ 繼承于HelloVB的類HelloCSharp
HelloMCPP   HelloVB    HelloCSharp

+Hello()    +Hello()    +Hello()
+Hello2()    +Add()    +Add()
+Add()       +Main()
**********************************************************************************
--使用VS2003創(chuàng)建一個VC的類-class library(.net)
1>HelloMCPP
//HelloMCPP.h
#pragma once
#include <stdio.h>
using namespace System;
namespace Wrox
{namespace ProCSharp
{namespace Assemblies
{namespace CrossLanguage
{public _gc class HelloMCPP //_gc 標(biāo)記類HelloMCPP,使類成為一個托管類
{public:
   virtual void Hello()
   {Console::WriteLine(S"Hello,ManagedC++");}//S作為字符串的前綴,托管的字符串就會寫入程序集,并用ldstr推入堆棧
  
   virtual void Hello2()
]   {printf("Hello,calling native code \n");}

   int Add(int val1,int val2)
   {return val1+val2;}
};
}}}}
**********************************************************************************
--使用VS2003創(chuàng)建一個VB.net的類-class library
--打開項目屬性,在Root Namespace 中將項目的根命名空間改為Wrox.ProCSharp.Assemblies.CrossLanguage
,這樣就改變了類的命名空間
--添加對HellpMCPP的引用:Project-->Add Reference
給項目添加引用就是將引用的程序集復(fù)制到VB.net項目的輸出目錄上(/bin),然后對原引用程序集的改變就是獨立的
2>HelloVB
public class HelloVB
   Inherits HelloMCPP

   public Overrides Sub Hello()
    MyBase.Hello() 'MyBase關(guān)鍵字代表基類,此處調(diào)用基類的方法
    Console.WriteLine("Hello,VB.NET")
   End Sub

   public Shadows Function Add(ByVal val1 as integer,_
     ByVal val2 as integer) as integer
    'Shadows關(guān)鍵字用來隱藏基類的方法Add(),因為在基類中Add()不是虛擬(virtual)的
    '不能被重寫
    return val1+val2
   End Function
End class
**********************************************************************************
--創(chuàng)建一個C#控制臺應(yīng)用程序,添加對HelloVB和HelloMCPP的引用
3>HelloCSharp
using System;
namespace Wrox.ProCSharp.Assemblies.CrossLanguage
{
   public class HelloCSharp:HelloVB
   {
    public HelloCSharp()
    {}

    public override void Hello()
    {
     base.Hello();
     Console.WriteLine("Hello,C#");
    }

    public new int Add(int val1,int val2)
    {
     return val1+val2;
    }

    [STAThread]

    public static void Main()
    {
     HelloCSharp hello new HelloCSharp();
     hello.Hello();
    }
   }
}
    
**********************************************************************************
最后控制臺應(yīng)用程序的輸出如下:
Hello,Managed C++
Hello,VB.NET
Hello,C#
*************************
因為所有的.net語言都生成MSIL代碼,所有的語言都使用.NET FRAMEWORK中的類,所以在性能上是沒有區(qū)別的
但仍有一些小的差別,首先,由于語言的不同,某些語言支持的數(shù)據(jù)類型其它語言不支持
其次,生成的MSIL代碼仍有差別
在默認(rèn)配置下,VB.NET上的執(zhí)行比較安全,C#上的執(zhí)行比較快,C#也更靈活
*************************
在基類中定義的方法在都可以在派生類中調(diào)用,如果方法的參數(shù)是System.UInt32數(shù)據(jù)類型,就不能在VB.NET中使用它
,因為VB.NET不支持無符號數(shù)據(jù)
無符號的數(shù)據(jù)類型與CLS不兼容,.net的語言不必支持這種數(shù)據(jù)類型
**********************************************************************************
.NET的語言
.NET consumer工具
   只使用.NET FRAMEWORK中的類,不能創(chuàng)建用于其它語言的.NET類;
   可以使用任何與CLS兼容的類
.NET extends工具
   可以滿足客戶的要求,可以繼承任何與CLS兼容的.NET類;
   定義了可以由客戶使用的新CLS兼容類
   C++,VB.NET,C#都是.NET extender工具,使用這些語言可以創(chuàng)建CLS兼容類

**********************************************************************************
CLSCompliant屬性
利用它可以把程序集標(biāo)記為與CLS兼容,這樣可以確保這個程序集中的類能用于所有的.NET consumer工具;
在公共方法或受保護(hù)的方法中使用與CLS不兼容的數(shù)據(jù)類型時,編譯器會給出警告;
在私有方法中使用什么樣的數(shù)據(jù)類型則不重要,因為在類的外部使用其它語言時,根本就不能訪問私有方法;
當(dāng)在公共方法和受保護(hù)的方法中使用與CLS不兼容的類型時,為了讓編譯器發(fā)出警告,可以設(shè)置程序集中的屬性
CLSCompliant,把這個屬性添加到AssemblyInfo.cs中:
[assembly:System.CLSCompliant(true)]
這樣,在程序集中定義的所有類型和公共方法就都是兼容的,當(dāng)參數(shù)的數(shù)據(jù)類型是不兼容的UINT時,編譯器就會發(fā)出如下
警告:error CS3001:Argument type uint is not CLS-compliant
把程序集標(biāo)記為兼容時,仍可以定義不兼容的方法,如果要重寫某些方法,使其參數(shù)是兼容和不兼容的數(shù)據(jù)類型,就必須把
類中的不兼容的方法的CLSCompliant屬性設(shè)置為false
CLSCompliant 屬性可以用到類型,方法,屬性,字段和事件上:
[CLSCompliant(false)]
void Method(uint i)
{//......
**********************************************************************************
CLS規(guī)則
程序集和與CLS兼容的要求:
方法原形中的所有類型都必須與CLS兼容;
數(shù)組元素的元素類型必須與CLS兼容。數(shù)組的第一個元素的下標(biāo)必須是0;
CLS兼容類必須繼承與CLS兼容類,當(dāng)然,System.Object 是與CLS兼容的;
在CLS兼容類中,方法名士不區(qū)分大小寫的,兩個方法不能僅根據(jù)其名稱中字母的大小寫來區(qū)分;
枚舉的類型必須是Int16,Int32,Int64,其它類型的枚舉都是不兼容的;
上述要求只適用于公共成員和受保護(hù)的成員,私有方法則無需考慮這些要求,它們可以使用不兼容的類型,
而程序集仍然是兼容的
還應(yīng)該遵循更一般的命名約定
C# VB.NET 更一般
int integer Int32
long long Int64
float single Single
在利用CLS規(guī)范和規(guī)則進(jìn)行編譯時,很容易創(chuàng)建出可以用于多種語言的組件,不需要使用所有的.NET FrameWork語言來測試該組件
**********************************************************************************
全局程序集緩存 Global Assembly Cache
可全局使用的程序集的緩存
大多數(shù)共享程序集都安裝在這個緩存中,其中也安裝了一些私有程序集
如果私有程序集使用本機圖像生成器編譯為本機代碼,編譯好的本機代碼也會存儲在這個緩存中
**********************************************************************************
本機圖像生成器 native image generator Ngen.exe
可以在安裝期間把IL代碼編譯為本機代碼,這樣程序啟動就比較快,因為不再需要在運行時進(jìn)行編譯
Ngen工具在本機圖像緩存中安裝本機圖像,本機圖像緩存是全局程序集緩存的一部分

**********************************************************************************
全局程序集緩存查看器
全局程序緩存可以使用shfusion.dll來顯示,它是一個Windows外殼擴(kuò)展程序,可以查看和處理緩存的內(nèi)容
Windows外殼擴(kuò)展程序是一個與Windows資源管理器集成的COM DLL
用戶啟動資源管理器,進(jìn)入<windir>/assembly目錄即可
可以查看全局程序集的名稱,類型,版本,文化和公鑰標(biāo)記,通過查看全局程序集的類型可以確定程序集是否
是使用本機圖像生成器安裝的
在該目錄下,有GAC和NativeImages_<runtime version>目錄,分別是共享程序集的目錄和編譯為本機代碼的程序集

**********************************************************************************
全局程序集緩存工具 gacutil.exe
全局程序集緩存查看器可以查看和刪除程序集,但不能在腳本代碼中使用該工具,例如創(chuàng)建安裝程序。
gacutil.exe 可以使用命令行安裝,卸載和顯示程序集
選項: gacutil /l   --顯示程序集緩存中的所有程序集
   gacutil /i mydll --把共享程序集mydll安裝到程序集緩存上
   gacutil /u mydll --卸載程序集mydll
   gacutil /ungen mydll --從本機圖像緩存中卸載程序集
**********************************************************************************
創(chuàng)建共享程序集
程序集可以由一個應(yīng)用程序使用,在默認(rèn)下部共享程序集,在使用私有程序集時,不需要考慮共享時需要考慮的任何要求
共享程序集名:必須是全局唯一的,1要保護(hù)該名稱,2要使得其他人不能使用這個名稱創(chuàng)建程序集
   COM使用全局唯一標(biāo)識符GUID只解決了第一個問題,第二個問題仍然沒有解決,每個人
都可以盜用這個GUID,用相同的標(biāo)識符創(chuàng)建不同的對象
   這兩個問題使用.NET程序集的強名都可以解決
   強名由以下項目組成:
     程序集本身的名稱
     版本號
     公鑰,保證強名是獨一無二的,并且保證引用的程序集不能被另一個源替代
     文化
共享程序集必須有一個強名,來唯一的標(biāo)識該程序集
每個程序集不能有新的公鑰,但可以在公司中有這樣一個公鑰,這樣該密鑰就唯一的標(biāo)識了公司的程序集
但是 ,這個密鑰不能用作信任密鑰,程序集可以利用Authenticode簽名來建立信任關(guān)系,
Authenticode中的密鑰可以與強名中使用的密鑰不同

**********************************************************************************
公鑰的加密
對稱加密:使用同一個密鑰進(jìn)行加密和解密
公鑰/私鑰加密:使用一個公鑰加密,使用對應(yīng)的私鑰解密/使用一個私鑰加密,使用對應(yīng)的公鑰解密
    成對創(chuàng)建公鑰和私鑰,公鑰可以任何人使用,甚至可以放在web站點上,但私鑰必須安全的加鎖
Sarah-->one email -->Julian,除了Julian外的人都不能看
使用Julian的公鑰加密,Julian打開該email,并使用他秘密存儲的私鑰解密
但還有一個問題,Julian不能確保email是Sarah發(fā)來的,任何人都可以使用Julian的公鑰加密發(fā)送email給他
解決辦法是黨Sarah發(fā)送email給Julian時,使用Julian的公鑰加密郵件之前他添加了自己的簽名,再使用自己的
私鑰加密該簽名,然后使用Julian的公鑰加密email,這個簽名可以使用Sarah的公鑰來解密,而Julian可以
訪問Sarah的公鑰,在解密了簽名后,Julian就可以確定是Sarah發(fā)送了email

**********************************************************************************
將公鑰/私鑰應(yīng)用于程序集
創(chuàng)建共享組件,必須使用公鑰/私鑰對
編譯器把公鑰寫入程序集清單,創(chuàng)建屬于該程序集的所有文件的散列表--用私鑰標(biāo)記這個散列表
私鑰不存儲在程序集中,確保沒有人可以修改這個程序集,簽名可以使用公鑰來驗證
在開發(fā)過程中,客戶程序集必須引用 共享程序集。編譯器把引用程序集的公鑰寫入客戶程序集的清單中
要減少存儲量,就不應(yīng)把公鑰寫入客戶程序集的清單,而應(yīng)寫入公鑰標(biāo)記,公鑰標(biāo)記是公鑰散列表中的最后8位字節(jié),且是唯一的
在運行期間加載共享程序集時(如果客戶程序集是使用本機圖像生成器安裝的,則應(yīng)在安裝期間加載),
共享程序集的散列表可以使用存儲在客戶程序集中的公鑰來驗證,除了私鑰的主人外其他人都不能修改共享程序集
例如:
銷售商A創(chuàng)建了一個組件Math,在客戶機上引用該組件,黑客的組件就無法替代它,只有私鑰的主人才能用
新版本來替換原來的共享組件,保證了其完整性

**********************************************************************************
創(chuàng)建共享程序集
例子
1 建立一個Visual C# Class Library 項目 SharedDemo,把命名空間改為Wrox.ProCSharp.Assemblies.Sharing
     類名改為SimpleShared
using System;
using System.Collection.Specialized;
using System.IO;

namespace Wrox.ProCSharp.Assemblies.Sharing
{
   public class SharedDemo
   {
    private StringCollection quotes;//類的構(gòu)造函數(shù)將文件的所有行都讀到其中
       //文件名作為參數(shù)傳遞到構(gòu)造函數(shù)
    private Random random;
   
    public SharedDemo(string filename)
    {
     quotes = new StringCollection();
     Stream stream =File.OpenFile(filename);
     StreamReader streamReader = new StreamReader(stream);
     string quote;
    
     while((quote=streamReader.ReadLine())!=null)
     {
      quotes.Add(quote);
     }
     streamReader.Close();
     stream.Close();
     random = new Random();
    }
    public string GetQuoteOfTheDay()
    //返回這個集合的一個隨機字符串
    {
     int index = random.Next(1,quotes.Count);
     retrun quotes[index];
    }
   }
}
*************************
* a>創(chuàng)建強名稱 *--程序集中有了公鑰
*************************
   要共享這個組件,需要一個強名稱,要創(chuàng)建這個名稱可以使用強名稱工具sn:
   sn -k mykey.snk
強名稱工具生成和編寫一個公鑰/私鑰對,并把該密鑰對寫到文件中,此處的文件是mykey.snk,現(xiàn)在可以
在向?qū)傻奈募嗀ssemblyinfo.cs中設(shè)置屬性AssemblyKeyFile,該屬性可以設(shè)置為密鑰文件的絕對路徑,也可以
設(shè)置為密鑰文件的相對路徑%ProjectDirectory\obj\<configuration>目錄,所以../../mykey.snk引用項目目錄中的
一個密鑰,在開始建立一個項目時,該密鑰安裝到Crypto Service Provider(CSP)中,如果該密鑰已經(jīng)安裝到CSP中,就可以
使用AssemblyKeyName屬性
下面是對Assemblyinfo.cs的修改
[assembly:AssemblyDelaySign(false)]
[assembly:AssemblyKeyFile("../../mykey.snk")]
[assembly:AssemblyKeyName("")]
在重新建立該文件后,使用ildasm查看該程序集,則該程序集的清單中應(yīng)有一個公鑰

*************************
* b>安裝共享程序集 *
*************************
使用全局程序集緩存工具gacutil及其/I選項把它安裝到全局程序集緩存中:
gacutil /i SharedDemo.dll
可以使用全局程序集緩存查看器檢查共享程序集的版本,看看它是否安裝成功

*************************
* c>使用共享程序集 *
*************************
創(chuàng)建一個C#控制臺應(yīng)用程序Client,不是把新項目添加到原來的解決方案中,而是創(chuàng)建一個新的解決方案
這樣在重新建立客戶時,就不會重新建立該共享程序集了。
以引用私有程序集方式引用程序集SimpleShared.dll,使用菜單Project|Add Reference
有了共享程序集,引用屬性CopyLocal就可以設(shè)置為false,這樣,共享程序集就不會復(fù)制到輸出文件的目錄下
而會從全局程序集緩存中加載
下面是客戶機應(yīng)用程序的代碼:
using System;
namespace Wrox.ProCSharp.Assemblies.Sharing
{
   class Client
   {
    [STAThread]
    static void Main(string[] args)
    {
     SharedDemo quotes = new SharedDemo(@"C:\ProCSharp\Assemblies\Quotes.txt");
     for(int i=0;i<3;i++)
     {
      Console.WriteLine(quotes.GetQuoteOfTheDay());
      Console.WriteLine();
     }
    }
   }
}
**********************************************************************************
公鑰的標(biāo)記也可以使用強名稱工具sn在共享程序集中查看:sn -T會顯示程序集中的公鑰標(biāo)記
sn -Tp顯示標(biāo)記和公鑰
**********************************************************************************
程序集的延遲簽名
公司的私鑰應(yīng)安全存儲,大多數(shù)公司不允許所有的開發(fā)人員訪問私鑰,只有幾個有安全權(quán)限的人才能訪問
這就是程序集的簽名可以以后(例如發(fā)布前)添加的原因
全局程序集屬性AssemblyDelaySign設(shè)置為true時,簽名就不會存儲在程序集中,但保留了足夠的空間,以便
以后添加。
但是不使用密鑰就不能測試程序集,在全局程序集緩存中安裝它
但可以使用臨時密鑰進(jìn)行測試,以后再用真正的密鑰代替這個臨時密鑰
程序集的延時簽名需要執(zhí)行以下步驟:
1>使用sn創(chuàng)建一個公鑰/私鑰對,生成文件mykey.snk,包含公鑰和私.snsn -k mykey.snk
2>提取公鑰,使之可以用于開發(fā)人員。選項-p提取密鑰文件的公鑰,文件mypublickey.snk僅包含公鑰
   sn -p mykey.snk mypublickey.snk
公司中所有開發(fā)人員都可以使用這個密鑰文件mypublickey.snk
在文件AssemblyInfo.cs中設(shè)置AssemblyDelaySign和AssemblyKeyFile屬性
[assembly:AssemblyDelaySign(true)]
[assembly:AssemblyKeyFile("../../mypublickey.snk")]
3>關(guān)閉簽名的驗證功能,因為程序集沒有包含簽名
sn -Vr ShareDemo.dll
4>在發(fā)布之前,程序集可以用sn工具重新簽名
-R選項用于對以前已簽名或延遲簽名的程序集進(jìn)行重新簽名
sn -R MyAssembly.dll mykey.snk
注意:簽名的驗證功能只能在開發(fā)過程中關(guān)閉,不經(jīng)過驗證是不能發(fā)布程序集的,因為這個程序集可能被懷有惡意的程序集代替
**********************************************************************************

程序集(assembly)是包含編譯好的、面向.NET Framework的代碼的邏輯單元。程序集是完全自我描述性的,也是一個邏輯單元而不是物理單元,它可以存儲在多個文件中(動態(tài)程序集的確存儲在內(nèi)存中,而不是存儲在文件中)。如果一個程序集存儲在多個文件中,其中就會有一個包含入口點的主文件,該文件描述了程序集中的其他文件。

注意可執(zhí)行代碼和庫代碼使用相同的程序集結(jié)構(gòu)。惟一的區(qū)別是可執(zhí)行的程序集包含一個主程序入口點,而庫程序集則不包含。

程序集的一個重要特性是它們包含的元數(shù)據(jù)描述了對應(yīng)代碼中定義的類型和方法。程序集也包含描述程序集本身的元數(shù)據(jù),這種程序集元數(shù)據(jù)包含在一個稱為程序集清單的區(qū)域中,可以檢查程序集的版本及其完整性。

注意:

ildasm是一個基于Windows的實用程序,可以用于檢查程序集的內(nèi)容,包括程序集清單和元數(shù)據(jù)。第15章將介紹ildasm。

程序集包含程序的元數(shù)據(jù),表示調(diào)用給定程序集中的代碼的應(yīng)用程序或其他程序集不需要指定注冊表或其他數(shù)據(jù)源,以便確定如何使用該程序集。這與以前的COM有很大的不同,以前,組件的GUID和接口必須從注冊表中獲取,在某些情況下,方法和屬性的詳細(xì)信息也需要從類型庫中讀取。

把數(shù)據(jù)分散在3個以上的不同位置上,可能會出現(xiàn)信息不同步的情況,從而妨礙其他軟件成功地使用該組件。有了程序集后,就不會發(fā)生這種情況,因為所有的元數(shù)據(jù)都與程序的可執(zhí)行指令存儲在一起。注意,即使程序集存儲在幾個文件中,數(shù)據(jù)也不會出現(xiàn)不同步的問題。這是因為包含程序集入口的文件也存儲了其他文件的細(xì)節(jié)、散列和內(nèi)容,如果一個文件被替換,或者被塞滿,系統(tǒng)肯定會檢測出來,并拒絕加載程序集。

程序集有兩種類型:共享程序集和私有程序集。

1.4.1 私有程序集

私有程序集是最簡單的一種程序集類型。私有程序集一般附帶在某些軟件上,且只能用于該軟件中。附帶私有程序集的常見情況是,以可執(zhí)行文件或許多庫的方式提供應(yīng)用程序,這些庫包含的代碼只能用于該應(yīng)用程序。

系統(tǒng)可以保證私有程序集不被其他軟件使用,因為應(yīng)用程序只能加載位于主執(zhí)行文件所在文件夾或其子文件夾中的程序集。

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

因為私有程序集完全是自含式的,所以安裝它的過程就很簡單。只需把相應(yīng)的文件放在文件系統(tǒng)的對應(yīng)文件夾中即可(不需要注冊表項),這個過程稱為“0影響(xcopy)安裝”。

1.4.2 共享程序集

共享程序集是其他應(yīng)用程序可以使用的公共庫。因為其他軟件可以訪問共享程序集,所以需要采取一定的保護(hù)措施來防止以下風(fēng)險:

       名稱沖突,另一個公司的共享程序集執(zhí)行的類型與自己的共享程序集中的類型同名。因為客戶機代碼理論上可以同時訪問這些程序集,所以這是一個嚴(yán)重的問題。

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

這些問題的解決方法是把共享程序集放在文件系統(tǒng)的一個特定的子目錄樹中,稱為全局程序集高速緩存(GAC)。與私有程序集不同,不能簡單地把共享程序集復(fù)制到對應(yīng)的文件夾中,而需要專門安裝到高速緩存中,這個過程可以用許多.NET工具來完成,其中包含對程序集的檢查、在程序集高速緩存中設(shè)置一個小的文件夾層次結(jié)構(gòu),以確保程序集的完整性。

為了避免名稱沖突,共享程序集應(yīng)根據(jù)私有密鑰加密法指定一個名稱(私有程序集只需要指定與其主文件名相同的名稱即可)。該名稱稱為強名(strong name),并保證其惟一性,它必須由要引用共享程序集的應(yīng)用程序來引用。

與覆蓋程序集相關(guān)的問題,可以通過在程序集清單中指定版本信息來解決,也可以通過同時安裝來解決。

1.4.3 反射

因為程序集存儲了元數(shù)據(jù),包括在程序集中定義的所有類型和這些類型的成員的細(xì)節(jié),所以可以編程訪問這些元數(shù)據(jù)。這個技術(shù)稱為反射,第11章詳細(xì)介紹了它們。該技術(shù)很有趣,因為它表示托管代碼實際上可以檢查其他托管代碼,甚至檢查它自己,以確定該代碼的信息。它們常常用于獲取特性的詳細(xì)信息,也可以把反射用于其他目的,例如作為實例化類或調(diào)用方法的一種間接方式,如果把方法上的類名指定為字符串,就可以選擇類來實例化方法,以便在運行時調(diào)用,而不是在編譯時調(diào)用,例如根據(jù)用戶的輸入來調(diào)用(動態(tài)綁定)。


本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
用.Net寫好的DLL如何能讓非.Net的程序使用呢?(如VB6)
40. C#
Assembly.Load
C#學(xué)習(xí)筆記(三)——各種頭銜的程序集
如何從程序集中加載及卸載插件(上)
C#將dll打包到程序中
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服