一,、GAC的作用 全稱是Global Assembly Cache作用是可以存放一些有很多程序都要用到的公共Assembly,,例如System.Data,、System.Windows.Forms等等,。這樣,,很多程序就可以從GAC里面取得Assembly,而不需要再把所有要用到的Assembly都拷貝到應(yīng)用程序的執(zhí)行目錄下面,。舉例而言,,如果沒有GAC,那么勢必每個(gè)WinForm程序的目錄下就都要從C:\WINDOWS\Microsoft.NET\Framework\vX下面拷貝一份System.Windows.Forms.dll,,這樣顯然不如都從GAC里面取用方便,,也有利于Assembly的升級和版本控制。 二,、強(qiáng)命名程序集 因?yàn)椴煌墓究赡軙_發(fā)出有相同名字的程序集來,,如果這些程序集都被復(fù)制到同一 個(gè)相同的目錄下,最后一個(gè)安裝的程序集將會代替前面的程序集,。這就是著名的Windows “DLL Hell”出現(xiàn)的原因,。 很明顯,,簡單的用文件名來區(qū)分程序集是不夠的,,CLR需要支持某種機(jī)制來唯一的標(biāo)識一個(gè)程序集,。這就是所謂的強(qiáng)命名程序集。 一個(gè)強(qiáng)命名程序集包含四個(gè)唯一標(biāo)志程序集的特性:文件名(沒有擴(kuò)展名),,版本號,語言文化信息(如果有的話),,公有秘鑰,。 這些信息存儲在程序集的清單(manifest)中。清單包含了程序集的元數(shù)據(jù),,并嵌入在程序集的某個(gè)文件中。 下面的字符串標(biāo)識了四個(gè)不同的程序集文件: “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” 如果一個(gè)公司想唯一的標(biāo)識它的程序集,那么它必須首先獲取一個(gè)公鑰/私鑰對,然后將共有秘鑰和程序集相關(guān)聯(lián)。不存在兩個(gè)兩個(gè)公司有同樣的公鑰/私鑰對的情況,正是這種區(qū)分使得我們可以創(chuàng)建有著相同名稱,版本和語言文化信息的程序集,,而不引起任何沖突,。 與強(qiáng)命名程序集對應(yīng)的就是所謂的弱命名程序集。(其實(shí)就是普通的沒有被強(qiáng)命名的程序集),。兩種程序集在結(jié)構(gòu)上是相同的,。都使用相同的PE文件格式,PE表頭,CLR表頭,,元數(shù)據(jù),,以及清單(manifest),。二者之間真正的區(qū)別在于:強(qiáng)命名程序集有一個(gè)發(fā)布者的公鑰/私鑰對簽名,,其中的公鑰/私鑰對唯一的標(biāo)識了程序集的發(fā)布者。利用公鑰/私鑰對,,我們可以對程序集進(jìn)行唯一性識別,、實(shí)施安全策略和版本控制策略,這種唯一標(biāo)識程序集的能力使得應(yīng)用程序在試圖綁定一個(gè)強(qiáng)命名程序集時(shí),,CLR能夠?qū)嵤┠承耙汛_知安全”的策略(比如只信任某個(gè)公司的程序集),。 三、如何創(chuàng)建強(qiáng)命名程序集, 如何查看強(qiáng)命名程序集的PublicKeyToken 如何創(chuàng)建強(qiáng)命名程序集 =================== 1. 在Visual Studio中的class library工程上點(diǎn)右鍵, 選擇properties. 2. 選擇左邊的Signing選項(xiàng)卡. 3. 勾選Sign the assembly復(fù)選框. 在下拉列表中選擇<New...>.
4. 在彈出的對話框中給snk文件起一個(gè)名字. 按OK.
5. 程序集強(qiáng)命名完成.
如何查看強(qiáng)命名程序集的public key token ========================= 有時(shí)候你需要在web.config文件中或者其他地方引用自己寫的強(qiáng)命名程序集, 你需要寫入像下面這樣的fully qualified name: MyNamespace.MyAssembly, version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e08
1. 在Visual Studio中, 打開Tools菜單, 然后點(diǎn)擊External Tools這個(gè)菜單項(xiàng). 2. 在彈出的External Tools對話框中, 點(diǎn)擊Add按鈕. 3. 按照下圖進(jìn)行配置. sn.exe這個(gè)工具在不同版本的VS下處于不同的文件夾中. 最簡單的找到它的方式是在VS Command Prompt中輸入"where sn.exe". 在參數(shù)框里寫入"-T $(TargetPath)". 然后勾選"Use Output Window". 這樣的話, 結(jié)果就會在VS的output window. 然后點(diǎn)擊OK,
4. 結(jié)果如圖.
5. 在輸出窗口可以看到結(jié)果. 這在你的solution里有多個(gè)project的時(shí)候也是可以正常工作的. 只需要點(diǎn)擊一下Solution Explorer中的Project, 然后點(diǎn)擊我們的菜單項(xiàng)就可以了.
四,、如何將自己的dll注冊到GAC中 在開發(fā)和測試中,,最常用的工具就是GACUtil.exe。 在GAC中注冊程序集跟COM注冊差不多,,但相對更容易: 例子: C:\Program Files\Microsoft Visual Studio 8\VC>gacutil -i F:\myweb\BalloonShop\Cl 在C:\WINDOWS\assembly將會看到ClassLibrary1,,注冊成功 五,、查看GAC文件內(nèi)容以及將DLL復(fù)制出來 在項(xiàng)目中我們常常會引入第三方的dll,一般情況下我們都可以將所需的dll文件復(fù)制到硬盤上的一個(gè)地方,,然后在項(xiàng)目中添加引用,,這個(gè)操作很簡單!但有時(shí)候我們會遇到這樣的情況,,就是所要引用的dll在目標(biāo)機(jī)器的GAC里,,這時(shí)我們就不能手動將它拷貝出來了。 其實(shí)Windows的GAC是有對應(yīng)的目錄的,,一般來說為c:\Windows\assembly\,,這個(gè)目錄有一些特殊,它里面存放的是本機(jī)已安裝和注冊的類庫dll,,并且不允許用戶直接對其中的元素進(jìn)行相關(guān)操作(如復(fù)制,、剪切、粘貼,、修改名稱等),,不過你可以直接將另一位置的dll文件直接拖放到這個(gè)目錄下進(jìn)行dll的安裝,但是我們不能直接將已經(jīng)安裝進(jìn)去的dll再拷貝出來,。這里我將介紹一種方法來完成這個(gè)操作,。 首先我們切換到Windows的命令行方式,即開始-運(yùn)行-cmd-回車,,然后轉(zhuǎn)到GAC所在的目錄,,利用dir命令查看一下其中的內(nèi)容,,如下圖。 似乎可以明白GAC中的目錄結(jié)構(gòu)了,,基本上我們可以根據(jù)GAC目錄中的Processor Architecture列來區(qū)分dir的類型,,例如我們要找的System.Web.Extensions屬于MSIL,在CMD方式下它應(yīng)該就對應(yīng)GAC_MSIL,,然后切換到這個(gè)目錄下并dir,。 看到我們要找的System.Web.Extensions程序集了,它也是一個(gè)dir,,繼續(xù)切進(jìn)去并dir,。 這時(shí)只有一個(gè)目錄了,繼續(xù)切進(jìn)去,,然后dir就可以看到我們最終想要的dll文件了,,然后通過copy命令將它復(fù)制出來就OK了! 小技巧:在CMD方式下使用命令時(shí),,如果要輸入的文件名或目錄名太長,,可以先敲部分字符,然后通過Tab鍵自動補(bǔ)全,,Windows的command工具會自動為你找到相匹配的內(nèi)容,! 六、例子 如上圖所示,,新建了2個(gè)類庫文件:ClassLibrary1,、ClassLibrary2 1、使用上面的第三點(diǎn)創(chuàng)建了強(qiáng)類型程序集ClassLibrary1,,并且注冊到GAC中(可以使用上面第三點(diǎn)的方法,,也可以使用反編譯器進(jìn)行反編譯,,可以查看到PublicKeyToken值。ClassLibrary2為null,ClassLibrary1為568e03e6162a7a2e),。2,、在DataAccess中引用ClassLibrary1,、ClassLibrary2,,編譯DataAccess。 3,、進(jìn)入DataAccess工程的bin\debug文件夾下,,只有ClassLibrary2.dll與DataAccess.dll(沒有ClassLibrary1.dll)由此可知:程序是從GAC中直接取得ClassLibrary1.dll的而不是從ClassLibrary1工程中將ClassLibrary1.dll拷貝到自身的debug中進(jìn)行引用。
|
|