2013-04-01 76 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更多的工作。 –

相关问题