情景還原: 今天一個朋友說網站不能上傳圖片,我檢查后發現一直卡住在上傳頁面,一直滾動,是個Fckeditor控件2.6.3的.
???????????? 經過google以后得到的結論是圖片上傳成功,但是沒有返回結果,在服務器上可以看到上傳的圖片. 說明是上傳控件有問題,程序不能返回結果.
???????????? 再google以后發現有人已經修改好了這個文件,FredCK.FCKeditorV2.dll,大喜,遂替換之,錯誤隨之而來.
錯誤原因:原來舊版本的dll文件與新版本的dll文件版本號不一樣,publickeytoken也可能不一樣,導致源程序在發布的時候,固定了這個版本號與publickeytoken.
解決辦法: 原版的程序沒有源代碼,所以不可能添加新的dll引用,再重新生成網站,所以只能替換. 發布的bin里面App_Web_0uxqio0i.dll這個文件引用了FredCK.FCKeditorV2.dll
???????????? 所以只需要修改App_Web_0uxqio0i.dll里面引用的FredCK.FCKeditorV2.dll的版本號以及publickeytoken就可以了.
原理是利用ildasm反編譯dll,再用ilasm編譯成dll再替換就可以了. 編譯了以后修改其中的版本號以及publickeytoken.????????????
引用:http://hi.baidu.com/zzyjg/blog/item/e8c0fb11ad932e19b9127be7.html
????????????
上午在打開一個Asp.net網頁時出現了這樣的錯誤信息:
找到的名為“Infragistics.WebUI.UltraWebGrid.ExcelExport.v3.1”的程序集清單定義與程序集引用不匹配。
其中Infragistics.WebUI.UltraWebGrid.ExcelExport.v3.1是我們程序中用到的第三方控件。我自己也是第一次遇到這樣的問題,咋一看估計是版本問題。但也不知道真正原因是什么以及該如何解決。上午查找了相應的資料將該“報錯”成功解決。
既然是“程序集清單”和“程序集引用”不匹配。那讓我們先來看看什么是“程序集清單”。
什么是程序集清單(Assembly Manifest)?
我們知道,在.net中。程序是以程序集為單位進行打包的,通常一個.exe文件或一個.dll文件就是一個程序集。程序集一般包含了以下幾個部分:
1,程序集清單(或者叫程序集元數據);
2,類型元數據;
3,MSIL代碼;
4,資源(可選項).
如此說來,一般情況下一個.exe或.dll都會包含這此內容。
具體請參考:http://msdn2.microsoft.com/zh-cn/library/zst29sk2(VS.80).aspx
在程序集中,程序集清單(manifest)是比較重要的,簡單地講它包含了一個程序集需要引用的外部分文件及程序集所包含的內容。其實也就是微軟說的“自我說明”。我們可以通過Visual Studio2003自帶的ILDASM工具查看該清單:
1,打開ILDASM,一般位于:VS2003安裝目錄\SDK\v1.1\Bin\目錄下。
2,打開ILDASM,后選擇文件->打開,將想要查看的程序集加進來。
3,雙擊“MANIFEST”;
打開后會看到如下內容:
上圖的MANIFEST就是程序清單,像紅線部分標出的是該程序集需要引用到外部文件Infragistics.WebUI.UltraWebGrid.ExcelExport.v3.1,同時也標識了版本號和密鑰。
至此,我們知道是什么是程序集清單以及怎么樣查看一個程序集清單了。下面我們再看看什么是程序集引用。
什么是程序集的引用?
在VS2003下編程的朋友們都知道,當我們用第三方控件,或是別人寫的DLL時,我所要做的就是將其引用進來。引用一個程序集的動作分為兩步:
首先,在項目中將需要的引用的程序集“添加至”引用中。
其次,在源文件件引入(using namespace)別人的命名空間;
如下:
如此將其引用進來以后,我們就可以使用該第三方控件提供的類、方法、資源等功能了。比如我們將“System.Data.SqlClient”引入以后,我們就可以通過其提供的類進行數據庫的連接及操作了。
現在知道什么是“程序集清單”了,知道什么是“程序集引用”。問題也相對明了了。程序引用中的第三方控件的版本號(我這邊是路徑導致的)和最終生成的程序集清單所需的版本號并不相符。
.net的CLR在執行一個程序時(如.exe)時或使用一個.dll時,他會首先查看其程序集(.exe或.dll)的程序集清單,找到運行該程序所引用的程序集并加載。.net會按一定的路徑搜索,加載.若加載的版本和程序清單中的不一致時就會出現類似"程序集清單定義與程序集引用不匹配"報錯。
利用dll轉存的.il文件,用記事本修改文件頭部中的版本號等資料.保存.
版本號直接右鍵屬性就可以看到了,publickeytoken需要用到命令. 參考http://blog.8384.org/post-470.html
使用命令行工具SDK Command Prompt,鍵入:SN -T C:\*****.dll
就會顯示出該dll具體的PublicKeyToken數值。
如果該程序集沒有強命名,則不會有PublicKeyToken數值。
將一個程序集強命名的方法是:
用SN -k C:\***.snk命令生成***.snk文件,將該snk文件加載到項目中。在項目上右鍵屬性,選擇Signing選項卡,鉤選中“Sign the assembly”,再在下拉列表中選擇剛才生成的***.snk,重新編譯程序集。
此后,該程序集就被強命名了,它的PublicKeyToken就有相應數值了。
注意要用大寫的-T,不能用小寫的。
公鑰標記由應用程序簽名時所用公鑰的SHA-1哈希代碼的最后8個字節表示
再用ilasm生成.
下面的命令對 MSIL 文件 myTestFile.il 進行匯編并產生可執行文件 myTestFile.exe.
下面的命令對 MSIL 文件 myTestFile.il 進行匯編并產生 .dll 文件 myTestFile.dll。
下面的命令對 MSIL 文件 myTestFile.il 進行匯編并產生 .dll 文件 myNewTestFile.dll。
ilasm myTestFile /dll /output:myNewTestFile.dll
這樣一個經過修改的dll文件生成了,再次替換文件.系統成功運行.已經可以識別新的版本的dll文件,并進行調用
上傳圖片成功.
ilasm 與 ildasm 點這里下載(打包在一起的):
http://files.cnblogs.com/cyrix/ildasm.rar