并非所有程序集都从bin文件夹加载到AppDomain中

时间:2012-04-23 16:56:35

标签: c# reflection assemblies

我有以下方法应该检索已加载的本地(在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?

3 个答案:

答案 0 :(得分:34)

Adil拥有它,但更详细:

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

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

另一件事:您可能需要考虑使用Location属性而不是CodeBase属性。 Location属性包含运行时加载的程序集的绝对路径。 CodeBase属性略有不同,对于项目的完整版本中的所有程序集可能不同。

答案 1 :(得分:6)

CurrentDomain.GetAssemblies()仅返回加载的程序集,而不是所有执行文件夹中可用的程序集。

这就是微软所说的“GetAssemblies方法,以获取已加载到应用程序域中的所有程序集的列表”。 click here

答案 2 :(得分:3)

尝试在这些缺少的程序集中启动任何类,然后再次运行代码。只有在第一次调用与该程序集相关的任何内容时才会加载程序集。