2012-04-23 78 views
13

我有以下的方法应该获取的加载本地(在bin文件夹)组件列表:不是所有的组件都被加载到AppDomain中bin文件夹

static IEnumerable<Assembly> GetLocalAssemblies() 
    { 
     Assembly callingAssembly = Assembly.GetCallingAssembly(); 
     string path = new Uri(Path.GetDirectoryName(callingAssembly.CodeBase)).AbsolutePath; 

     var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
     return assemblies.Where(x => !x.IsDynamic && new Uri(x.CodeBase).AbsolutePath.Contains(path)).ToList(); 
    } 

但是,组件列表中缺少我需要它的几个组件。我需要的程序集是被管理的(c#.net 4),在项目中被引用,并存在于bin文件夹中。

为什么二进制文件中存在的bin文件夹不扫,进入应用程序启动时的AppDomain中?

+0

出于好奇,什么是路径字符串的值? – 2012-04-23 17:01:36

+0

这是该项目的bin文件夹的路径。 – 2012-04-23 17:12:20

回答

24

Adil有它,但更详细:

.NET CLR使用即时编译。除此之外,这意味着它在首次使用时加载程序集。因此,尽管程序集正在使用程序集引用,但如果CLR尚未执行程序所需的引用,它们不会被加载,因此不会出现在当前AppDomain中的程序集列表中。

另一件可能适用或不适用的问题是,如果您在GAC中具有相同版本的程序集,则CLR将优先于本地程序集使用GAC,除非在DEVPATH环境中指定了这些程序集的路径变量。如果是这种情况,并且CLR使用任何“缺失”程序集的GAC副本,则它们将具有不同的CodeBase值,并且不会显示在您的Linq查询结果中。其他

一两件事:你可能要考虑使用位置属性,而不是将codebase属性。 Location属性包含在运行时加载的程序集的绝对路径。 CodeBase属性稍有不同,并且对于完整构建项目中的所有组件都可能不同。

+0

+1位置属性。 – Turbot 2012-04-23 17:14:25

+1

+1“如果CLR不需要引用,它们将不会出现在当前AppDomain的程序集列表中。”<---唉。这是一个杀死我的bug的根本问题。 – jwatts1980 2017-01-24 19:17:06

4

的CurrentDomain.GetAssemblies()只返回加载的程序集不它们是在执行文件夹中提供的所有组件。

这就是微软说些什么“GetAssemblies方法来获取已加载到应用程序域的所有组件的列表。” click here

3

尝试启动任何类在这些缺少组件,然后再次运行代码..只在需要时与第一次调用与该组件的任何程序集加载。

相关问题