NET 查找程序集路径(CLR关于Assembly的搜索路径的过程)
最近在回顾.Net应用程序的执行环境,这里做一个很小的总结,方面以后需要的时候进行查找:

CLR必须可以找到正确的Assembly,Net提供了Assembly搜索算法,可以根据.config文件(类似于.ini)自定义assembly搜索。
算法分析过程如下:
1、 在GAC(Global Assembly Cache)中搜索相应版本的DLL.
2、 配置文件(web.config或app.config)中
3、 应用程序(.exe)当前目录下
4、 配置文件(web.config或app.config)
OK,CLR就是根据上面的顺序从1到4进行搜索Assembly的。如果没有搜索到指定版本的DLL,则程序会抛出异常,提示:DLL文件无法找到。
下面通过程序DEMO来演示这个搜索算法:
我们新建立一个ClassLibary,名称为:NetLibraryTest,并且在一个类Charles.cs中建立一个方法GetVersion(),为了测试CLR 查找DLL的顺序,我们针对上面的4个顺序实现4个不同的NetLibraryTest.dll 即:
一、GAC(Global Assembly Cache)
public class Charles2008
{
public string GetVersion()
{
return "GAC";
}
}
二、CodeBase元素
public class Charles2008
{
public string GetVersion()
{
return "CodeBase";
}
}
三、应用程序根目录:
public class Charles2008
{
public string GetVersion()
{
return "CurrentRoot";
}
}
四、Privatepath路径
public class Charles2008
{
public string GetVersion()
{
return "Privatepath";
}
}
编译上面的4中不同的方法,即得到4个不同的NetLibraryTest.dll文件,另外为了放到GAC中,需要为该dll生成publicKeyToken的值。
OK,下面我另外建立一个项目:Console应用程序NetVersionTest.exe:(代码很简单)
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Begin Process");
try
{
NetLibraryTest.Charles2008 Charles = new NetLibraryTest.Charles2008();
Console.WriteLine(Charles.GetVersion());
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
Console.WriteLine("End Process");
Console.ReadLine();
}
}
配置文件NetVersionTest.exe.config的内容如下:
<?xml version="1.0" encoding="utf-8" ?>
< configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<probing privatePath="PrivatePath"/>
<assemblyIdentity name="NetLibraryTest"
publicKeyToken="a5015e7d589eac1d"
culture="neutral" />
<codeBase version="1.0.242.0" href="CodeBase\NetLibraryTest.dll" />
</dependentAssembly>
</assemblyBinding>
</runtime>
< /configuration>
好了,代码部分就完成了,最后我们生成一个exe文件NetVersionTest.Exe,另外也去掉一些额外的文件,我们这样定义如下的结构:

备注:CodeBase文件夹下存放对应的NetLibaryTest.dll文件。即返回值为”CodeBase”。
同理:PrivatePath文件夹下也存放的是对应的NetLibaryTest.dll文件,即返回值:”PrivatePath”。
GAC文件夹也存放对应的NetLibaryTest.dll文件,即返回值:”GAC”。
OK,下面讨论几种情况:
1. 如果GAC里面的NetLibaryTest.dll文件放到GAC中去了,则最后NetVersionTest.exe首先会从GAC中里面去寻找,即最后输出:”GAC”
2. 如果NetLibaryTest.dll没有GAC中注册,则根据前面的顺序,NetVersionTest.exe则会调用CodeBase文件夹下的DLL.即最后输出:”CodeBase”
3. 如果在NetVersionTest.exe.config文件中没有CodeBase元素的配置的话,根据顺序则会调用到应用程序根目录下的NetLibaryTest.dll,即最后输出:”CurrentRoot”.
4. 最后一种情况:没有在GAC中注册,没有配置CodeBase,而且应用程序目录下也没有NetLibaryTest.dll文件,则CLR会从Probing的PrivatePath路径下去寻找指定的dll
5. 如果在1.2.3.4情况下都没有找到的话,则会发生异常,提示不能加载指定版本的dll文件。

说明一下:上面我测试用的Demo的那NetLibaryTest.dll是强名称的程序集,如果是弱名称的程序集则不会再GAC中去寻找(也就是跳过了第一步)。
为了更好的说明CLR搜索程序集的顺序,下面用一个流程图来表示:

附:
(1) 初始化绑定。基本上,这意味着从元数据中取出相关的AssemblyRef记录,并查看其中包括什么内容--它的外部程序集名称,它是否经过强命名,是否指定了文化等。
(2) 应用版本策略。这是一些由应用程序、被引用的共享程序集发布者或管理员生成的语句。这些语句包含在XML配置文件中,并且只是将程序集的特定版本(或一组版本)重定向到不同的版本。
NET 查找程序集路径(CLR关于Assembly的搜索路径的过程)的更多相关文章
- 显示python已安装模块及路径,添加修改模块搜索路径
在python交互模式下输入: help('modules') #可以显示出已安装的模块 在python交互模式下输入: import sys sys.path #可以显示出模块搜索路径 增加搜索路径 ...
- Linux下包含头文件的路径问题与动态库链接路径问题
C/C++程序在linux下被编译和连接时,GCC/G++会查找系统默认的include和link的路径,以及自己在编译命令中指定的路径.自己指定的路径就不说了,这里说明一下系统自动搜索的路径. [1 ...
- Python 学习 第十五篇:模块搜索路径和包导入
在导入自定义的模块时,除了指定模块名之外,也需要指定目录,由于Python把目录称作包,因此,这类导入被称为包导入.包导入把计算机上的目录变成Python的命名空间,而目录中所包含的子目录和模块文件则 ...
- 针对程序集 'SqlServerTime' 的 ALTER ASSEMBLY 失败,因为程序集 'SqlServerTime' 未获授权(PERMISSION_SET = EXTERNAL_ACCESS)
错误: 针对程序集 'SqlServerTime' 的 ALTER ASSEMBLY 失败,因为程序集 'SqlServerTime' 未获授权(PERMISSION_SET = EXTERNAL_A ...
- 配置.net程序集搜索路径
默认情况下,.net程序对外部程序集dll的搜索路径是exe文件所在的目录,虽然这种方式没有什么太多不好的地方,但是当我们引用外部程序集较多的时候显得非常杂乱.一种比较常用的解决方式是通过配置在app ...
- 3/21 Django框架 模板路径及模板过滤器 1.模板路径查找
3/21 Django框架 模板路径及模板过滤器 1.模板路径查找 先找settings.py里的TEMPLATES列表下的DIRS路径.如果APP_DIRS为True,还会到注册了的APP文件夹下依 ...
- python 搜索路径顺序查找
但我们通过 import 或者frome .. import...查找模块的时候,当你导入一个模块,Python 解析器对模块位置的搜索顺序是 1.当前目录 2, 如果不在当前目录,Python 则搜 ...
- maven的安装、路径配置、修改库文件路径和eclipse中的配置、创建maven工程。
注:本文来源于:杨四郎2018 <maven的安装.路径配置.修改库文件路径和eclipse中的配置.创建maven工程> 一.maven的安装 首先,先到官网去下载maven.这里是官 ...
- gcc编译时头文件和库文件搜索路径
特殊情况:用户自定义的头文件使用#include"mylib"时,gcc编译器会从当前目录查找头文件 一.头文件 gcc 在编译时寻找所需要的头文件 : ※搜寻会从-I开始( ...
随机推荐
- Bash美化
首先声明下,这些美化方式都不是我自己想的,而是多个牛人的方法. 第一:简单点 这个方法来自于:http://www.vimer.cn/?p=1554 没有美化前是这样,鼠标光标在很右边: 在.bash ...
- wpf的datepicker处理
如果有2个datepicker,控制时间起和止的话,可以把第二个datepicker加一个属性,DisplayDateStart = "{Binding SelectedDate,Eleme ...
- core java 8~9(GUI & AWT事件处理机制)
MODULE 8 GUIs--------------------------------GUI中的包: java.awt.*; javax.swing.*; java.awt.event.*; 要求 ...
- CoverFlow效果
1. 成员函数 mCamera是用来做类3D效果处理,比如z轴方向上的平移,绕y轴的旋转等 mMaxRotationAngle是图片绕y轴最大旋转角度,也就是屏幕最边上那两张图片的旋转角度 mMaxZ ...
- Hadoop之Hive UDAF TopN函数实现
public class GenericUDAFTopNRow extends AbstractGenericUDAFResolver { @Overridepublic GenericUDAFEva ...
- UITableView 表视图编辑
UITableViewController(表视图控制器)继承自UIViewController,自带一个tableView self.view不是UIView而是UITableView dataso ...
- PHP自定义函数使用外部变量
一般,php的自定义函数不能直接使用外部变量. 在php自定义函数中使用外部变量前,需要先使用global对外部变量进行声明. <?php $var = "hello World!& ...
- Data Developer Center > Learn > Entity Framework > Get Started > Loading Related Entities
Data Developer Center > Learn > Entity Framework > Get Started > Loading Related Entitie ...
- html <input>标签类型属性type(file、text、radio、hidden等)详细介绍
html <input>标签类型属性type(file.text.radio.hidden等)详细介绍 转载请注明:文章转载自:[169IT-最新最全的IT资讯] html <inp ...
- Django ajax MYSQL Highcharts<1>
Another small project with django/Ajax/Mysql/Highcharts. 看下效果图 - delivery dashboard .嘿嘿 是不是还蛮好看的. 废 ...