.NET 查找程序集路径(CLR关于Assembly的搜索路径的过程)
2011-08-16 16:34
495 查看
最近在回顾.Net应用程序的执行环境,这里做一个很小的总结,方面以后需要的时候进行查找:
CLR必须可以找到正确的Assembly,Net提供了Assembly搜索算法,可以根据.config文件(类似于.ini)自定义assembly搜索。
算法分析过程如下:
1、 在GAC(Global Assembly Cache)中搜索相应版本的DLL.
2、 配置文件(web.config或app.config)中
<codebase version=”Assembly Version" href=”URL of assembly” />
3、 应用程序(.exe)当前目录下
4、 配置文件(web.config或app.config)
<probing privatePath=”Paths” />
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配置文件中,并且只是将程序集的特定版本(或一组版本)重定向到不同的版本。
CLR必须可以找到正确的Assembly,Net提供了Assembly搜索算法,可以根据.config文件(类似于.ini)自定义assembly搜索。
算法分析过程如下:
1、 在GAC(Global Assembly Cache)中搜索相应版本的DLL.
2、 配置文件(web.config或app.config)中
<codebase version=”Assembly Version" href=”URL of assembly” />
3、 应用程序(.exe)当前目录下
4、 配置文件(web.config或app.config)
<probing privatePath=”Paths” />
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的搜索路径的过程) .
- NET 查找程序集路径(CLR关于Assembly的搜索路径的过程)
- 关于2003Server下IIS运行.net程序IE无法访问出现403.1错误的解决过程
- 关于程序动态库链接和运行时搜索路径设置的个人理解
- 关于2003Server下IIS运行.net程序IE无法访问出现403.1错误的解决过程
- .Net应用程序的执行环境(CLR关于Assembly的搜索算法)
- 调试用Python C API 写的程序问题还真多,关于import搜索路径的,复制过来,以防忘记
- 关于.net web项目打包安装程序安装过程中出现安装未完成的解决办法
- 关于程序动态库链接和运行时搜索路径设置的个人理解
- 妥善处理好代码书写过程中关于路径中分隔符“/”的方方面面
- 关于Norton扫描与.Net程序出错
- .NET 数据库存储过程执行快,程序调用存储过程执行慢
- .net知识和学习方法系列(十六)CLR-托管理程序和它的运行
- Linux下gcc编译中关于头文件与库文件搜索路径相关问题(二)
- .Net,你为什么会慢 (托管程序与非托管程序启动过程)
- 关于C/C++程序里如何实现模糊查找
- ASP.NET结合存储过程写的通用搜索分页程序
- 在WEB程序中使用.NET Remoting的IpcChannel时注意事项(关于“拒绝访问”问题的解决)
- 程控制中关于搜索、控制计算机的功能 和 VB中截获shell程序的输出
- IE7中“查找更多提供程序”(搜索栏菜单里)的链接地址