什么可能导致system . typeloadeexception
本文关键字:system typeloadeexception 什么 | 更新日期: 2023-09-27 18:10:04
我正在使用VS2008,使用c#开发一个应用程序,用于霍尼韦尔海豚6100,一个带有条形码扫描器的移动计算机,使用Windows CE 5.0操作系统。
我想添加一个可以将文件从本地设备发送到远程服务器的功能。我找到了图书馆"塔米尔。夏普"。这可以保证这一点。我在控制台应用程序和普通的windows窗体应用程序上测试了代码,它运行得很好。但是当我试图在winCE设备上使用相同的代码时,我得到一个typeloadeexception,并且我有错误消息:
<>之前无法加载"Tamir.SharpSsh"类型。SshTransferProtocolBase' from assembly 'Tamir。SharpSSH,版本=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();
有人对此有什么想法吗?我会非常感激!!
可以是任何东西。可能的原因有:
- 无法找到程序集
- 找不到您的程序集所依赖的程序集
- 找到程序集,但类型不在其中
- 类型的静态构造函数抛出异常
最好的办法是使用Fusion日志查看器来帮助诊断。文档在这里:
http://msdn.microsoft.com/en-us/library/e74a18c4 (v = vs.110) . aspx
(仅供参考,"Fusion"是设计装配加载系统的团队的代号;有点不幸的是,代码名最终出现在发货产品的文件名中。这个东西应该被称为"AssemblyBindingLogViewer.exe"或类似的东西)
Eric Lippert的答案完美地描述了这种情况。
我只是想添加一个关于这种异常的帮助页面通常不涉及的情况的快速答案。
我已经创建了一个快速&一些开源项目的脏测试项目(Akka。我给这个项目命名为"Akka"。
它可以完美地构建,但是在启动时,它会抛出关于Akka.dll中的类的类型加载异常。
这只是因为我的可执行文件(akka.exe)和引用文件(akka.dll)有相同的名称。我花了几分钟才弄明白这一点(我一开始是通过复制本地、目标平台、准确版本……等等)。
这是一些非常愚蠢的东西,但不是你会想到的第一件事(特别是因为我使用nuget来依赖),所以我认为分享它可能会很有趣:如果你的EXE和依赖有相同的名字,你会遇到typeloadeexception。
我不知道我是如何管理的,但出于某种原因,我在GAC(全局程序集缓存)中有一个旧版本的DLL。试着在那里寻找一个旧的组件并将其移除。
这可能是由许多事情引起的,MSDN说:
当公共语言运行库找不到程序集、程序集中的类型或无法加载类型时,将抛出typeeloadeexception。
所以很明显找不到类型,要么是程序集丢失了,要么是类型丢失了,要么是运行时配置之间存在冲突。
有时会出现问题,因为您引用的程序集与您正在使用的程序集是不同的平台类型(32位/64位等)。
我建议捕获异常并更详细地检查它,以确定它出了什么问题。
有时我看到这个问题出现,因为(由于这样或那样的原因)一个被引用的程序集实际上不能被解析,即使它被引用和加载。
我通常在涉及AppDomain边界时看到这种情况。
我发现有时解决这个问题的一种方法(但只有当程序集已经在AppDomain中时)是这个代码片段:AppDomain.CurrentDomain.AssemblyResolve += (s, e) =>
{
return AppDomain.CurrentDomain.GetAssemblies()
.SingleOrDefault(asm => asm.FullName == e.Name);
}
就像我说的,当AppDomains参与进来时,我看到了这个问题,当程序集确实已经被引用和加载时,这似乎解决了这个问题。我不知道为什么框架不能解决引用本身。
通过在注册表中启用一些设置,可以将加载器日志文件从. net Compact Framework中取出。. net Compact Framework的Power Toys包括一个名为netcfloging的工具,它可以为您设置注册表值。
注册表值记录在这里:
http://msdn.microsoft.com/en-us/library/ms229650(v=VS.90).aspx
在我的例子中,问题原来是名称空间冲突。我在解决方案中有多个启动项目,其Main()在类Program中,并且我发现我在相同的命名空间中定义了多个Program类,尽管在不同的程序集中。
在我的案例中,问题是我有两个项目在一个解决方案中使用相同的库。我只在第一个项目中更新了dll。因此,当我构建解决方案时,第二个项目将覆盖第一个项目的dll(项目构建顺序)。
的例子:
解决方案:
——MainProject
——MyDll v5.3.2.0
——原型
——MyDll v5.0.0.0
在第二个项目中更新dll后问题消失。
确保名称(名称空间,类名称等)是它们应该是什么。当我不得不重新开始我的项目时,我得到了这个错误,我从模板中复制了我的类的内容,未能将类名称从"模板类"更改为正确的名称(它应该与项目名称相匹配)。
typeName字符串参数必须是完全限定类型名
例如:Activator.CreateInstance("assemblyFullName"," namspace .typename")
My TypeLoadException是由FieldOffset(1)的struct引起的
无法加载类型"…"因为它包含一个偏移量为1的对象字段,该字段与非对象字段不正确对齐或重叠
带有以
开头的结构定义[StructLayout(LayoutKind.Explicit, Pack = 1)]
unsafe struct Metadata
{
[FieldOffset(0)]
public readonly byte Length;
[FieldOffset(1)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string ApplicationName;
...
在我的情况下,这个问题是由新版本软件的一部分方法引起的,但是当以前的版本加载时,这些方法根本不存在。我的解决方案是创建一个单独的类,其中包含一个版本中可用的所有方法,并且在主类中,我只在检查版本后调用该单独的类。如果你正在使用Revit API,你可以这样做:
application.ControlledApplication.VersionNumber