熱門話題VB.NET DLL搜索路徑經(jīng)典講解
有些人都認為VB.NET DLL搜索路徑和VC一樣,什么Path路徑、系統(tǒng)路徑。但是其實它們是不一樣的。在網(wǎng)上收集了一些資料,現(xiàn)在我們來看看吧。我印象當中,VB.NET DLL搜索路徑要么是exe目錄,要么是GAC,要么是config文件指定的目錄。可惜config只能提供給exe使用,dll沒有cinfig。
托管模塊(Managed Module)
托管模塊是一個需要CLR才能執(zhí)行的標準Windows可移植可執(zhí)行(portable executable,簡稱PE)文件。
元數(shù)據(jù)(Metadata)
簡單的講,元數(shù)據(jù)就是一個數(shù)據(jù)表的集合,在這些表中,其中一些用于描述托管模塊中所定義的內(nèi)容(比如所定義的類型和它們的成員),另外還有一些用于描述托管模塊中所引用的內(nèi)容(比如被引用的類型和它們的成員)。
- URL: ms-help://MS.MSDN
- QTR.2004APR.1033/cpguide/html/cpconmetadataoverview.htm
程序集清單(Assembly Manifest)
程序集清單是另外一些元數(shù)據(jù)表的集合。這些表描述了組成程序集的文件,程序集所有文件中實現(xiàn)的公有導出類型,以及一些程序集相關的資源文件或數(shù)據(jù)文件。
- ms-help://
- MS.MSDNQTR.2004APR.1033/cpguide/html/cpconAssemblyManifest.htm
1.程序集(Assembly)的概念:
首先:程序集是一個或多個托管模塊,以及一些資源文件的邏輯組合。因為它是一個邏輯上的組合,所以程序集的邏輯表示和物理表示可以相互分離。如何將代碼和資源劃分到不同的文件中完全取決于我們。例如,我們可以將一些很少使用的類型或資源放在一個單獨的Assembly Module中,然后根據(jù)需要(比如第一次用到的時候),從web上下載它們。如果沒有用到,它們將不會被下載。這樣既節(jié)省磁盤空間,也減少了安裝時間。程序集允許我們將文件的部署分解開來,同時又將所有的文件看作一個單獨的集合。
其次:因為CLR是直接和程序集打交道的,所以程序集也是組件復用,以及實施安全策略和版本策略的最小單元(安全策略,版本信息等都只能是加在程序集上)。
注意:程序集是一個邏輯組合,它可以包含很多個文件。大多數(shù)程序集(比如使用Visual Studio.NET創(chuàng)建的那些)一般都是單文件程序集,也就是只有一個.exe或者.dll文件(目前.NET的程序集只有這兩種格式)。在這種情況下,程序集清單(manifest)直接嵌入到單文件程序集中。但是,你也可以用“程序集生成工具”(Al.exe)來創(chuàng)建多文件程序集。也可以只創(chuàng)建一個只包含清單的程序集。
2.強命名程序集(Strong Name Assembly)的概念
因為不同的公司可能會開發(fā)出有相同名字的程序集來,如果這些程序集都被復制到同一 個相同的目錄下,最后一個安裝的程序集將會代替前面的程序集。這就是著名的Windows “DLL Hell”出現(xiàn)的原因。
很明顯,簡單的用文件名來區(qū)分程序集是不夠的,CLR需要支持某種機制來唯一的標識一個程序集。這就是所謂的強命名程序集。 一個強命名程序集包含四個唯一標志程序集的特性:文件名(沒有擴展名),版本號,語言文化信息(如果有的話),公有秘鑰。 這些信息存儲在程序集的清單(manifest)中。清單包含了程序集的元數(shù)據(jù),并嵌入在程序集的某個文件中。
下面的字符串標識了四個不同的程序集文件:
- “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”
如果一個公司想唯一的標識它的程序集,那么它必須首先獲取一個公鑰/私鑰對,然后將共有秘鑰和程序集相關聯(lián)。不存在兩個兩個公司有同樣的公鑰/私鑰對的情況,正是這種區(qū)分使得我們可以創(chuàng)建有著相同名稱,版本和語言文化信息的程序集,而不引起任何沖突。
與強命名程序集對應的就是所謂的弱命名程序集。(其實就是普通的沒有被強命名的程序集)。兩種程序集在結構上是相同的。都使用相同的PE文件格式,PE表頭,CLR表頭,元數(shù)據(jù),以及清單(manifest)。二者之間真正的區(qū)別在于:強命名程序集有一個發(fā)布者的公鑰/私鑰對簽名,其中的公鑰/私鑰對唯一的標識了程序集的發(fā)布者。利用公鑰/私鑰對,我們可以對程序集進行唯一性識別、實施安全策略和版本控制策略,這種唯一標識程序集的能力使得應用程序在試圖綁定一個強命名程序集時,CLR能夠實施某些“已確知安全”的策略(比如只信任某個公司的程序集)。
3.如何創(chuàng)建強命名程序集(Strong Name Assembly)
創(chuàng)建一個強命名程序集首先需要獲得一個用強命名實用工具 (Strong Name Utility,即SN.exe,.NET SDK自帶)產(chǎn)生的密鑰。下面簡要介紹一下SN.exe的一些用法。 要產(chǎn)生一個公鑰/私鑰對:
a)SN –k MyCompany.Keys
該命名告訴SN.exe創(chuàng)建一個名為MyCompany.keys的文件。MyCompany.keys文件將包含以對以二進制格式存儲的公有密鑰和私有密鑰。
b)查看公有密鑰:
首先生成一個只包含公有密鑰的文件:
- SN –p
- MyCompany.keys MyCompany.PublicKey
然后用-tp參數(shù)查看:
創(chuàng)建好了公鑰/私鑰對,創(chuàng)建強命名程序集就很容易了。只需要把System.Reflection.AssemblyKeyFileAttribute特性加入到源代碼中就可以了:?[assembly:AssemblyKeyFile("MyCompany.keys")] 說明:公鑰/私鑰對文件的擴展名可以是任意的(也可以沒有),因為編譯的時候都是以元數(shù)據(jù)的格式讀取的。
- SN –tp MyCompany.PublicKeys
- Public key is
- 00240000048000009400000006020000002400005253413
- 10004000001000100bb7214723ffc13901343df4b9c464ebf
- 7ef4312b0ae4d31db04a99673e8163768cc0a2a7062e731d
- beb83b869f0509bf8009e90db5c8728e840e782d2cf928dae
- 35c2578ec55f0d11665a30b37f8636c08789976d8ee9fe9a5
- c4a0435f0821738e51d6bdd6e6711a5acb620018658cce93
- df37d7e85f9a0104a5845053995ce8
- Public key token is 2dc940d5439468c2
4.程序集的部署方式
一個程序集有兩種部署方式:
a)私有方式
和應用程序部署在同一目錄下的程序集稱作私有部署程序集。弱命名程序集只能進行私有部署。
b)全局方式
全局部署方式將程序集部署在一些CLR已確知的地方,當CLR搜索程序集時,它會知道到這些地方去找。強命名程序集既可以進行私有部署,也可以進行全局部署。
5.如何部署強命名程序集(Strong Name Assembly)和GAC
a)GAC的概念
如果一個Assembly要被多個應用程序訪問,那么他就必須放在一個CLR已確知的目錄下,并且CLR在探測到有對該Assembly的引用時,它必須能自動到該目錄下尋找這個程序集。這個已確知的目錄稱作GAC(Global Assembly Cache),就是全局程序集緩存。它一般位于下面的目錄下:
GAC的作用就是提供給CLR一個已知的確定的目錄去尋找引用的 程序集。
b)GAC的內(nèi)部結構
GAC是一個特殊的結構化的目錄,用Windows Explorer瀏覽你會以為它只是一個包含很多程序集的普通目錄。其實不是這樣的,在命令行下查看,你會發(fā)現(xiàn)它實際上包含很多子目錄,子目錄的名字和程序集的名稱是相同的,但它們都不是實際的程序集,實際的程序集位于程序集名對應的目錄下。比如進入GCFWK子目錄,我們會發(fā)現(xiàn)其中又有很多的子目錄。 機器內(nèi)每一個安裝到GAC的GCFWK.dll在GCFWK中都會有一個子目錄。
這里只 有一個目錄表明只有一個版本的GCFWK程序集被安裝。實際的程序集保存在每一個對應的版本目錄下。目錄的名稱以下劃線的形式分割為“(Version)_(Culture)_(PublicKeyToken)”。
【編輯推薦】






