什么可能导致System.TypeLoadException?

我正在使用C#开发VS2008,这是一款适用于霍尼韦尔Dolphin 6100的应用程序,这是一款带有条形码扫描仪的移动计算机,它使用Windows CE 5.0,如操作系统。

我想添加一个function,可以将文件从本地设备发送到远程服务器。 我找到了可以保证这一点的图书馆“ Tamir.SharpSSH ”。 我在控制台应用程序和普通的Windows窗体应用程序上测试了代码,它运行得很好。 但是当我尝试在winCE设备上使用相同的代码时,我得到一个TypeLoadException并且我有错误消息:

无法从程序集'Tamir.SharpSSH加载'Tamir.SharpSsh.SshTransferProtocolBase'类型,   
 Version = 1.1.1.13,Culture = neutral,PublicKeyToken = null'。

我使用的代码如下所示:

SshTransferProtocolBase sshCp = new Scp(Tools.GlobalVarMeth.hostName, Tools.GlobalVarMeth.serverUserName); sshCp.Password = Tools.GlobalVarMeth.serverUserpassword; sshCp.Connect(); string localFile = Tools.GlobalVarMeth.applicationPath + "/" + fileName + ".csv"; string remoteFile = Tools.GlobalVarMeth.serverRemoteFilePath + "/" + fileName + ".csv"; sshCp.Put(localFile, remoteFile); sshCp.Close(); 

有谁对此有任何想法? 我真的很感激!!!

它可以是任何数量的东西。 可能的原因是:

  • 无法找到该组件
  • 无法找到assembly所依赖的assembly体
  • 找到了程序集,但类型不在其中
  • 类型的静态构造函数抛出exception

您最好的选择是使用Fusion日志查看器来帮助诊断它。 文档在这里:

http://msdn.microsoft.com/en-us/library/e74a18c4(v=vs.110).aspx

(仅供参考“Fusion”是设计assembly加载系统的团队的代号;有些不幸的是,代码名称最终出现在已发货产品的文件名中。该东西应该被称为“AssemblyBindingLogViewer.exe”或者一些这样的事情。)

Eric Lippert的答案完美地描述了这种情况。

我只想添加一个关于案例的快速回答,该案例通常不包含在有关此例外的帮助页面中。

我为一些开源软件创建了一个快速而肮脏的测试项目(Akka.Net,将其命名),我将项目命名为“Akka”。

它完美构建,但在启动时会抛出类型加载exception关于Akka.dll中的类。

这只是因为我的可执行文件(akka.exe)和引用(akka.dll)具有相同的名称。 我花了几分钟来计算这一点(我开始使用复制本地,目标平台,确切版本等等)。

这是非常愚蠢但不强行的第一件事你会想到(特别是因为我使用nuget作为依赖),所以我认为分享它会很有趣:如果你的EXE和依赖名称相同,你会遇到TypeLoadException。

这可能是由任何数量的事情造成的,MSDN称它为:

当公共语言运行库找不到程序集,程序集中的类型或无法加载类型时,抛出TypeLoadException。

所以很明显无法找到类型,缺少程序集,缺少类型或运行时配置之间存在冲突。

有时会出现问题,因为您引用的程序集是与您正在使用的程序集不同的平台类型(32位/ 64位等)。

我建议捕获exception并更详细地检查它以确定它有什么问题。


继我之前的信息

有时我看到这个问题出现是因为(出于某种原因)引用的程序集实际上无法解析,即使它被引用和加载。

我通常在涉及AppDomain边界时看到这一点。

我发现有时解决问题的一种方法(但只有当程序集已经在AppDomain中时)才是这个小代码片段:

 AppDomain.CurrentDomain.AsemblyResolve += (s, e) => { return AppDomain.CurrentDomain.GetAssemblies() .SingleOrDefault(asm => asm.FullName == e.Name); } 

就像我说的那样,当AppDomains参与其中时,我看到了这个问题,当组件确实已经被引用和加载时,这似乎解决了它。 我不知道为什么框架无法解析引用本身。

这差点让我发疯了……

我不知道我是如何管理它的,但由于某种原因,我在GAC中有一个旧版本的DLL。 尝试在那里寻找旧组件并将其移除。

祝你好运!

您可以通过在注册表中启用某些设置来从.NET Compact Framework中获取加载程序日志文件。 Power Compact for .NET Compact Framework包含一个名为NETCFLogging的工具,它为您设置注册表值。

注册表值记录在此处:

http://msdn.microsoft.com/en-us/library/ms229650(v=VS.90).aspx

在我的情况下,问题是我有两个项目在一个解决方案中使用相同的库。 我只在第一个项目中更新了DLL。 因此,当我构建解决方案时,第二个项目是从第一个项目(项目构建顺序)中覆盖DLL。

例:

解:

–MainProject

—— MyDll v5.3.2.0

– 原型

—— MyDll v5.0.0.0

在第二个项目中更新DLL后问题消失了。

确保名称(名称空间,类名等)是它们应该是的。 当我不得不重新开始我的项目时,我遇到了这个错误,我从模板中复制了我的类的内容,并且无法将类名从“模板类”更改为正确的名称(它应该与项目名称匹配) 。