2013-04-01 72 views
2

有一個項目已從.NET 3.5遷移到.NET 4.0。該項目有一些對.NET 1.0程序集的引用,這些程序集是COM對象的包裝程序。這些.NET 1.0程序集和COM對象是外部公司的產品。該項目編譯,但在運行時期間在第一點當軟件引用了那些1.0組件定義的對象拋出異常:在.NET 4.0遷移後引用.NET 1.0程序集的System.TypeLoadException

System.TypeLoadException: Could not load the structure 'ESRI.MapObjects2.Core.ShapeTypeConstants' from assembly 'ESRI.MapObjects2.Core, Version=2.4.1.0, Culture=neutral, PublicKeyToken=8fc3cc631e44ad86'.

結構被標記爲獲型等價,但它有一個靜態或非公有領域。實際的「結構」是一個枚舉,在反射它看起來像這樣:

[Guid("B027CAB1-6908-11D2-AF98-006097DA3688")] public enum ShapeTypeConstants { moShapeTypeEllipse = 0x1a, moShapeTypeLine = 0x16, moShapeTypeMultipoint = 0x18, moShapeTypePoint = 0x15, moShapeTypePolygon = 0x17, moShapeTypeRectangle = 0x19 }

的內部異常是空的。我可以看到0x80131522(-2146233054)的HRESULT,意思是COR_E_TYPELOAD。我不認爲我有任何丟失的本地dll或程序集,因爲我們的.NET工作正常(並且它使用相同的代碼,相同的引用)。

如何解決此異常?有沒有簡單的方法,如在dll的配置文件中指定requiredRuntime或在csproj的參考部分中指定requiredTargetFramework?

+0

什麼是給定的'TypeLoadException'的'InnerException'? –

+0

使用[供應商支持論壇](http://forums.arcgis.com/forums/59-MapObjects?s=efd1427d2bef5d9c6805bfd987d9ccaa) –

+0

Hans:我做到了。 MapObjects2是停產產品。我期望在那裏直接面向新的ArcGIS API,但我正在尋求更簡單的修復方法。 http://forums.arcgis.com/threads/81091-Game-over-The-structure-is-marked-as-eligible-for-type-equivalence-but-it-has-... –

回答

0

如果情況很糟糕,那我也可以玩得很粗暴。

如果我們看看實際的錯誤消息,它會抱怨「結構」中的「靜態或非公共」字段。所謂的結構實際上是一個枚舉。貌似在COM層上包裝枚舉。有幾十種各種包裝枚舉,每個值都明確指定。每個枚舉也包含一個名爲「value__」的私有變量。更具體地說,它看起來是這樣的: .field private specialname rtspecialname int32 value__

那麼,爲什麼我們不只是單純地讓他們公開:

  1. 拆卸與ILDASM源。
  2. 將私人範圍限定符替換爲public(如果我正確記得它:49個位置被替換)。
  3. 最後,我使用修改後的IL中的ilasm編譯dll。

瞧!生成的DLL(ESRI.MapObjects2.Core.dll)爲311.296字節,而原始長度爲323.584字節,這使我仍然有點懷疑。但是,如果我用我的修改後的版本覆蓋GAC中的原始dll,那麼事情就會起作用,我們的軟件不會再炸燬。我無法確認100%的工作是否正常,因爲我不瞭解我們軟件的GIS部分。但是我迄今爲止設法得到的是確定的。 什麼可以讓別人擔心:如果公共變量的存在會改變任何結構佈局,它可能會導致枚舉值或其他混合的偏移。但希望它不會混淆任何東西。這是一個快速入侵,在生產中它需要在MapObjects42安裝後覆蓋GAC中的ESRI.MapObjects2.Core.dll。嘆。 所以我不一定會告訴任何人,但它似乎有效,它給了我一些滿足感,某種復仇的感覺。黑客在一天結束時給了我一點幸福。

+0

如何:編輯Interop程序集,簡單:http://msdn.microsoft.com/en-us/library/8zbc969t.aspx –

0

也許可能爲別人提供的解決方案:忽略供應商提供的.NET wrapper DLL,並直接從我們的項目中引用底層的COM組件。這由Joe Parker在此主題中描述:http://social.msdn.microsoft.com/Forums/zh-CN/vblanguage/thread/81c44b22-7bdc-4379-b0f6-953e1f96adfe。 「我們能夠通過將MapObjects 2.3作爲COM組件引用而不是使用MapObjects附帶的.NET dll來解決這個問題。刪除ESRI。從您的項目引用,然後添加對COM組件「ESRI MapObjects 2.3」的引用。這將使用.NET代碼包裝COM組件,這些代碼將在VS 2010中實際運行。

然後,對於可視組件,右鍵單擊工具箱和「選擇項目」。從「COM組件」選項卡中選擇「MapObjects 2.3 Map Control」,然後您就可以將控件添加到表單中。在我的情況下,我不得不將它添加到表單,然後將其刪除,以便Visual Studio會自動將對「AxMapObjects2」的引用添加到項目中。該參考具有視覺控制和一些支持類型。然後,我用AxMapObjects2.AxMap和其他類型的MapObjects2.AxMap和其他類型替換了我們的舊的AxMap引用,並且一切正常(至少目前爲止)。「

他的方法也可以推廣到其他類似的情況:」app < - > vendor .NET wrapper < - > vendor COM objects「。不幸的是,在我們的例子中,這個方法可能不那麼容易,因爲我們不僅在應用程序中託管了COM控件,而且在我們的軟件的其他模塊中,導入功能和其他零散的東西,所以我不能只參考那裏的GUI COM組件,我只需要其他地方的一些核心功能,但我想我會分享這個發現,這可能對別人有幫助,我100%確定不是MapObjects2和我們的應用程序將是唯一的受害者。隨着更多的項目將遷移到.NET 4.0,仍然有一些舊的遺留負擔面對這個。

+0

更長期的解決方案可以是在我的特定情況下轉換到更新的API(ArcGIS)。但是這需要比dll更多的工作。 –

相關問題