31

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

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

无法从程序集“Tamir.SharpSSH”加载类型“Tamir.SharpSsh.SshTransferProtocolBase”,   
版本=1.1.1.13,文化=中性,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();

有人对此有任何想法吗?我将不胜感激!!!

4

9 回答 9

42

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

  • 找不到该程序集
  • 找不到您的程序集所依赖的程序集
  • 找到程序集,但类型不在其中
  • 类型的静态构造函数抛出异常

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

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

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

于 2013-04-18T14:59:40.660 回答
25

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

我只想添加一个关于此异常的帮助页面通常不涵盖的案例的快速答案。

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

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

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

这是您首先想到的非常愚蠢但并非强制的第一件事(特别是因为我将 nuget 用于依赖项),所以我认为分享它可能会很有趣:如果您的 EXE 和依赖项具有相同的名称,您将遇到 TypeLoadException。

于 2015-08-25T13:19:00.713 回答
5

这几乎把我逼疯了……

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

祝你好运!

于 2017-06-22T07:38:28.597 回答
3

这可能是由许多事情引起的,MSDN 说:

当公共语言运行时找不到程序集、程序集中的类型或无法加载类型时,将引发 TypeLoadException。

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

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

我建议捕获异常并更详细地检查它以确定它遇到的问题。


根据我之前的信息

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

当涉及 AppDomain 边界时,我通常会看到这一点。

我发现有时可以解决问题的一种方法(但仅当程序集已经在 AppDomain 中时)是此代码段:

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

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

于 2013-04-18T14:51:58.597 回答
1

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

此处记录了注册表值:

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

于 2013-04-30T12:15:01.263 回答
1

就我而言,问题原来是命名空间冲突。我在解决方案中有多个启动项目,它们的 Main() 在类 Program 中,我发现我在同一个命名空间中定义了多个 Program 类,尽管在不同的程序集中。

于 2021-10-01T04:51:49.580 回答
0

确保名称(命名空间、类名等)是它们应有的名称。当我不得不重新开始我的项目并且我从模板中复制了我的类的内容并且未能将类名从“模板类”更改为正确的名称时出现此错误(它应该与项目名称匹配) .

于 2018-06-27T13:41:06.600 回答
0

typeName 字符串参数必须是完全限定的类型名称

例如:Activator.CreateInstance("assemblyFullName","namespace.typename")

于 2019-10-22T12:37:54.440 回答
0

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

例子:

解决方案:

--主要项目

------MyDll v5.3.2.0

- 原型

------MyDll v5.0.0.0

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

于 2017-11-16T12:18:21.860 回答