代码之家  ›  专栏  ›  技术社区  ›  edosoft

列出从GAC实现特定接口的所有DLL

  •  2
  • edosoft  · 技术社区  · 17 年前

    阿罗哈

    给定一个插件体系结构(C/.NET 3.5),其中包含存储在GAC中的插件,如何列出/加载包含实现特定接口的类型的所有DLL?换句话说,我想通过查看GAC来调查我的应用程序的哪些插件安装在机器上。

    -爱德华

    5 回复  |  直到 17 年前
        1
  •  3
  •   Darin Dimitrov    17 年前

    首先要澄清一点:一个DLL不能实现一个接口。DLL包含可以实现特定接口的类型。这里有一个 .NET wrapper 围绕fusion.dll,它允许您枚举GAC中的所有程序集。加载程序集后 Assembly.Load 您可以尝试查找实现特定接口的所有类型:

    foreach (var type in assembly.GetTypes())
    {
        var myInterfaceType = typeof(IMyInterface);
        if (type != myInterfaceType && myInterfaceType.IsAssignableFrom(type))
        {
            Console.WriteLine("{0} implements IMyInterface", type);
        }
    }
    
        2
  •  4
  •   Neil Williams    17 年前

    为了增加bfree的答案,我建议你可以 load the assemblies for reflection only . 这使您在没有AppDomain的情况下增强了安全性(程序集根本无法执行)和灵活性(您可以加载用于不同体系结构的程序集)。

        3
  •  3
  •   BFree    17 年前

    GAC实际上只是您机器上的一个目录,与其他任何目录一样。以下是典型的故障:

    c:\windows\assembly\GAC
    
                       \GAC_32
    
                       \GAC_MSIL
    

    也许还有其他的……

    在每个文件夹中,您将找到存储实际dll的子文件夹。您首先需要编写一个递归方法来获取在\assembly\下找到的所有dll(如果您自己不愿意,可以很容易地在网上找到这些dll)。一旦您有了DLL的列表,您就可以继续使用assembly.loadfile加载程序集,并检查所有类型是否实现了给定的接口。

    我唯一的建议是在单独的AppDomain中加载这些dll,这样您就不会允许任何潜在的有害dll加载到您的应用程序中。

    一些链接:

    Searching Directories.

    Loading Assemblies and checking for a given interface.

    Creating new AppDomain.

        4
  •  1
  •   JP Alioto    17 年前

    你应该看看 Type Selector Tool 在企业库中。它可能不是您直接想要的,但它可以完成您所描述的,并且您可以从中借用一些实现。

        5
  •  0
  •   Jonathan Rupp    17 年前

    首先,我建议 这样做。为此,必须从GAC加载所有程序集。我建议您让您的用户(或管理员或其他人)告诉您要从哪个程序集加载程序集(尽管为此,您可能需要一个所有选项的列表,这可能是您请求此操作的原因…)

    也就是说,这可能有效,但它会为几个它应该有效的程序集抛出错误,我不确定为什么……另外,我不知道如何检测GAC在哪里——C:\windows\assembly是默认的,但我不知道实际值存储在哪里(注册表?)

    var targetType = typeof(IComparable);
    var errors = new List<Exception>();
    var c = Directory.GetFiles(@"c:\windows\assembly", "*.dll", SearchOption.AllDirectories).ToList()
        .ConvertAll(f => Path.GetFileNameWithoutExtension(f))
        .Where(f => !f.EndsWith(".ni"))
        .Distinct().ToList()
        .ConvertAll(f => { try { return Assembly.ReflectionOnlyLoad(f); } catch (Exception ex) { errors.Add(ex); return null; } })
        .Where(a => a != null)
        .SelectMany(a => { try { return a.GetTypes(); } catch (Exception ex) { errors.Add(ex); return new Type[] { }; } })
        .Where(t => targetType.IsAssignableFrom(t));
    

    祝你好运。

    推荐文章