CSharp Tips:引用ActiveX/COM組件時的Strong Name

問題
DotNet平臺下提供了比較完備的類庫,但是第一個版本總歸不可能面面俱到,而且由於歷史遺留問題,經常會和COM/ActiveX的組件之間進行互操作。
筆者碰到的問題就是在一個Assembly中調用到了Excel的對象,但是該Assembly需要封裝成爲一個ActiveX的Control,供IE的客戶端腳本調用。簡而言之,我在C#中用到了一個COM組件,還需要把自己封裝成一個COM組件,聽起來有點多餘不過想不到更好的辦法。
在這樣的封裝模式下碰到了一個問題,如果一個Assembly希望封裝成爲ActiveX/COM組件,那麼它必須擁有強名(Strong Name),也就是說在編譯的時候需要指定SNK(Strong Name Key)。但是當一個Assembly如果以擁有強名的方式編譯的話,它又要求所以自身所引用的其他Assembly都必須擁有強名,否則不能夠成功編譯。而當我們在工程中直接引用一個COM組件(例如:Excel 10 Object Library),VS.Net能夠幫助我們自動導入類型庫,但是此時的引用類型庫是沒有強名的,在筆者所期望的環境下無法編譯成功。
 
解決
碰到這個問題覺得很棘手,似乎陷入和死循環,不過查閱一下文檔,發現還是非常容易解決的,DotNet Framework中提供了相應的工具能夠轉換COM的類型庫,他就是TlbImp.exe(大家可以在類似“C:/Program Files/Microsoft Visual Studio .NET 2003/SDK/v1.1”的目錄中找到)。TlbImp能夠將一個COM組件包裝成爲DotNet可以使用的類庫的形式,VS.Net的自動轉換想必也是以來這個工具。該工具有很多參數開關,需要支持強名只要額外打開一個開關即可。一下介紹筆者認爲最可能用到的參數:
/out:Filename:類型庫轉換之後輸出文件的名稱。
/namespace:Namespace:類型庫轉換所使用的名稱空間。
/keyfile:FileName:指定轉換時使用的SNK文件,指明該參數,構造之後的類型庫就擁有了強名。
完整的例子如下:
tlbimp excel.exe /out:interop.excel.dll /namespace:Excel /keyfile:excel.snk
其中snk文件可以通過DotNet中的另一個工具SN生成,此處不再贅述。
完成上述工作,在工程中直接引用我們自己構造的類型庫,就可以成功的編譯擁有強名的DLL了。
 
如果是控件,而不是普通的Component,那麼就不能夠使用tlbimp,而需要使用aximp.exe這個工具,使用方法與tlbimp類似,他會生成兩個文件:一個是類型庫的代理文件,另一個是Windows Form的代理文件。
 
進一步解決
然而還有更加簡單的解決辦法,就是在工程屬性中設置“Wrapper Assembly Key File”(Common Properties/General/Wrapper Assembly Key File),這個屬性。設置了該屬性之後通過Add Reference添加的COM/ActiveX組件,都將被標識,擁有強名。
這需要一次設置就可以了,應該更加方便。
 
 
參考文檔
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章