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

Byr*_*ahl 20 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();
    }  
Run Code Online (Sandbox Code Playgroud)

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

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

Kei*_*thS 36

阿迪尔有它,但更详细:

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

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

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

  • +1“如果CLR不需要引用,它们将不会出现在当前AppDomain中的程序集列表中”。这是一个导致我丧命的错误的根本原因。 (2认同)

Adi*_*dil 8

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

这就是微软所说的"GetAssemblies方法,以获取已加载到应用程序域中的所有程序集的列表".点击这里


小智 5

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