ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

解决反射时ReflectionTypeLoadException异常

2021-06-12 13:34:47  阅读:116  来源: 互联网

标签:反射 exe ReflectionTypeLoadException 文件 dll Main 异常 目录


在GIS开发程序中,为了增加扩展性,往往采用插件式开发模式,自然用到了反射技术。如果反射使用的dll控制不好,很容易引发反射异常,查找原因十分不方便,可以使用PrettyBin或Costura等组件实现对类库的管理。

问题描述

使用主程序Main.exe反射调用A.dll文件时,出现"未处理 System.Reflection.ReflectionTypeLoadException Message="无法加载一个或多个请求的类型。有关更多信息,请检索LoaderExceptions属性。",代码如下:

var assembly = Assembly.LoadFile(filePath);
var types= assembly.GetTypes(); //引发ReflectionTypeLoadException异常

进一步查看LoaderExceptions异常,发现是因为缺少B.dll或它的某一个依赖项。

未能加载文件或程序集"B, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"或它的某一个依赖项。系统找不到指定的文件。

A.dll确实引用了B.dll,但仔细核对和检查了所有dll文件都在A.dll所在目录,没有发现缺失的情况。

这种错误一般只有两种原因:一是dll文件不能被调用主程序找到二是dll文件能找到,但版本不对。实际上,B.dll和A.dll虽然是在相同目录,但与Main.exe不同,使用Main.exe反射调用其他算子时,它只会在Main.exe所在目录 去找B.dll,当然找不到,所以报错。

解决方案

方法一: AssemblyResolve事件

一种解决方法是注册当前域(AppDomain.CurrentDomain)的AssemblyResolve事件,即当反射调用A.dll文件时,它找不到B.dll,就会触发此事件,在这个事件中手动找路径。这种方法的缺点时,需要手动指定路径,不方便修改。

方法二: privatePath配置

为了动态修改目录,可直接在AppConfig配置中指定dll所在的目录,如下:

<configuration>
…..
	<runtime>
		<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
			<probing privatePath="目录1; 目录2" />
		</assemblyBinding>
	</runtime>
</configuration>

当程序在exe所在的目录找不到dll时,它会依次在目录1、目录2中找,如果还找不到就报错!

当然也可以用代码来实现,自动添加软件目录下所有文件夹作为privatePath的值。

参考连接

关于跨程序集的反射 - torome - 博客园 (cnblogs.com)

AppDomain.CurrentDomain.AssemblyResolve - mCat - 博客园 (cnblogs.com)

c# 用代码来设置程序的PrivatePath_夏仲达的博客-CSDN博客_privatepath

标签:反射,exe,ReflectionTypeLoadException,文件,dll,Main,异常,目录
来源: https://www.cnblogs.com/liweis/p/14878085.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有