System.TypeLoadException 在 .NET 4.0 迁移后引用 .NET 1.0 程序集 [英] System.TypeLoadException referencing .NET 1.0 assemblies after .NET 4.0 migration

查看:25
本文介绍了System.TypeLoadException 在 .NET 4.0 迁移后引用 .NET 1.0 程序集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有一个从 .NET 3.5 迁移到 .NET 4.0 的项目.该项目有一些对 .NET 1.0 程序集的引用,这些程序集是 COM 对象的包装器.这些 .NET 1.0 程序集和 COM 对象是外部公司的产品.项目可以编译,但在运行期间,当软件引用那些 1.0 程序集中定义的对象时,第一点会引发异常:

There's a project which was migrated from .NET 3.5 to .NET 4.0. The project has some references to .NET 1.0 assemblies, which are wrappers around COM objects. These .NET 1.0 assemblies and COM objects are product of an external company. The project compiles, but during runtime the first point when the software references an object defined in those 1.0 assemblies throws an exception:

System.TypeLoadException:无法从程序集ESRI.MapObjects2.Core,Version=2.4.1.0,Culture=neutral,PublicKeyToken=8fc3cc631e44ad86"加载结构ESRI.MapObjects2.Core.ShapeTypeConstants".

该结构被标记为符合类型等效,但它有一个静态或非公共字段.实际的结构"是一个枚举,在 Reflector 中它看起来像这样:

The structure is marked as eligible for type equivalence, but it has a static or non-public field. The actual "structure" is an enum, in Reflector it looks like this:

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

内部异常为空.我可以看到 0x80131522 (-2146233054) 的 HRESULT,这意味着 COR_E_TYPELOAD.我不认为我有任何缺失的本机 dll 或程序集,因为我们的 .NET 工作正常(并且它使用相同的代码、相同的引用).

The inner Exception is null. I can see a HRESULT of 0x80131522 (-2146233054), it means COR_E_TYPELOAD. I don't think I have any missing native dlls or assemblies, because our .NET works fine (and it uses the same code, same references).

如何解决这个异常?是否有一种简单的方法,例如在 dll 的配置文件中指定 requiredRuntime 或在 csproj 的参考部分中指定 requiredTargetFramework?

How to fix this exception? Is there an easy way like specifying requiredRuntime in dll's config files or requiredTargetFramework in csproj's Reference section?

推荐答案

如果环境恶劣,那我也可以玩得不亦乐乎.

If the circumstances are rough, then I can play rough too.

如果我们看一下实际的错误消息,它会抱怨结构"中的静态或非公开"字段.所谓的结构其实就是一个枚举.似乎是 COM 层上的包装枚举.有更多的各种包装枚举,每个值都明确指定.每个枚举还包含一个名为value__"的私有 int 变量.更具体地说,它看起来像这样:.field private specialname rtspecialname int32 value__

If we take a look at the actual error message, it's complaining about a "static or non-public" field in the "structure". The so called structure is actually an enum. Seemingly a wrapper enum on the COM layer. There are more dozens of various wrapper enums, each value is specified explicitly. Each of the enums also contain one private int variable named "value__". More specifically it looks like this: .field private specialname rtspecialname int32 value__

那么我们为什么不简单地将它们公开:

So why don't we just simply make them public:

  1. 使用 ildasm 反汇编源代码.
  2. 将私有范围限定符替换为 public(如果我没记错的话:替换了 49 个位置).
  3. 最后,我使用修改后的 IL 中的 ilasm 编译了一个 dll.

瞧!生成的 dll (ESRI.MapObjects2.Core.dll) 为 311.296 字节,而原始文件的长度为 323.584 字节,这让我仍然有点怀疑.但是,如果我用修改后的 dll 覆盖 GAC 中的原始 dll,一切正常,我们的软件就不会再爆炸了.我无法确认一切都 100% 有效,因为我并不真正了解我们软件的 GIS 部分.但是到目前为止我设法做到的还可以.令人担心的是:如果公共变量的存在会改变任何结构布局,它可能会导致枚举值的偏移或其他混淆.但希望它不会混淆任何东西.这是一个快速的技巧,在生产中它需要在安装 MapObjects42 后覆盖 GAC 中的 ESRI.MapObjects2.Core.dll.叹.所以我不一定向任何人推荐它,但它似乎有效,它给了我一些满足,某种报复的感觉.一天结束时,黑客给了我一点快乐.

And voila! The resulting dll (ESRI.MapObjects2.Core.dll) is 311.296 bytes, while the original is 323.584 bytes long, which makes me a little suspicious still. But if I overwrite the original dll in the GAC with my modified one, things work, our software doesn't blow up any more. I cannot confirm that everything 100% works, because I don't really know the GIS part of our software. But what I managed to get so far is OK. What can make someone worry: if the presence of the public variable would change any structure layout, it might cause the shift of the enum values, or other mixup. But hopefully it won't mix up anything. This is a quick hack, and in production it'd require the overwrite of the ESRI.MapObjects2.Core.dll in GAC after the MapObjects42 installation. Sigh. So I don't necessarily advise it to anyone, but it seems to work, and it gave me some satisfaction, some kind of revenge feeling. Hacking gave me a little happiness at the end of the day.

这篇关于System.TypeLoadException 在 .NET 4.0 迁移后引用 .NET 1.0 程序集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆