22

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

4

3 回答 3

41

Adil 有,但更详细:

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

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

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

于 2012-04-23T17:04:17.823 回答
11

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

这就是微软所说的“GetAssemblies 方法来获取已加载到应用程序域中的所有程序集的列表”。点击这里

于 2012-04-23T17:01:36.160 回答
5

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

于 2012-04-23T17:02:30.200 回答