C# 列出所有DLL';s从GAC实现一个特定的接口

C# 列出所有DLL';s从GAC实现一个特定的接口,c#,plugins,gac,C#,Plugins,Gac,阿罗哈 给定一个带有存储在GAC中的插件的插件体系结构(C#/.NET 3.5),我如何列出/加载包含实现我的特定接口的类型的所有dll?换句话说,我想通过查看GAC来调查计算机上安装了哪些应用程序插件 -eNodeGac实际上就像其他目录一样,只是您机器上的一个目录。以下是典型的故障: c:\windows\assembly\GAC \GAC_32 \GAC_MSIL 也许还有其他一些 在每个文件夹中,您都可以找

阿罗哈

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


-eNode

Gac实际上就像其他目录一样,只是您机器上的一个目录。以下是典型的故障:

c:\windows\assembly\GAC

                   \GAC_32

                   \GAC_MSIL
也许还有其他一些

在每个文件夹中,您都可以找到存储实际dll的子文件夹。您首先需要编写一个递归方法,以获得在\assembly\下找到的所有dll(如果您自己不习惯这样做,您可以很容易地在线找到这些dll)。一旦有了dll列表,就可以继续使用Assembly.LoadFile加载程序集,并检查所有类型以查看它们是否实现了给定的接口

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

一些链接:


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

foreach (var type in assembly.GetTypes())
{
    var myInterfaceType = typeof(IMyInterface);
    if (type != myInterfaceType && myInterfaceType.IsAssignableFrom(type))
    {
        Console.WriteLine("{0} implements IMyInterface", type);
    }
}

您应该查看企业库中的。它可能不是您直接想要的,但它实现了您所描述的,您可能可以从中借用一些实现。

要补充BFree的答案,我建议您可以。这使您在没有appdomains的情况下获得了增强的安全性(程序集根本无法执行)和灵活性(您可以加载用于不同体系结构的程序集)

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

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

var targetType=typeof(可比较);
var errors=新列表();
var c=Directory.GetFiles(@“c:\windows\assembly”、“*.dll”、SearchOption.AllDirectories).ToList()
.ConvertAll(f=>Path.GetFileNameWithoutExtension(f))
其中(f=>!f.EndsWith(“.ni”))
.Distinct().ToList()
.ConvertAll(f=>{try{return Assembly.reflectiononnlyload(f);}catch(Exception ex){errors.Add(ex);return null;}})
.其中(a=>a!=null)
.SelectMany(a=>{try{return a.GetTypes();}catch(Exception ex){errors.Add(ex);return new Type[]{};}})
其中(t=>targetType.IsAssignableFrom(t));

祝你好运。

小更正:dll(程序集)不实现接口,但它们可能包含实现接口的类。请原谅我的无知,插件dll是否属于gac?不在应用程序的应用程序文件夹中?通常不在。插件应该与加载到的应用程序一起使用。然而,如果这些是多应用程序插件,那么我可以理解为什么人们希望将它们放在GAC中。如果你这样做了,我将有配置来加载它们,而不仅仅是从GAC加载所有的。我不能夸大使用另一个AppDomain的重要性。事实上,积极回收AppDomain可能是一个更好的选择,因为加载的每个程序集都会增加内存消耗。在编写我的程序集时,我没有注意到darin的答案——与读取c:\windows\assembly中的文件相比,gacapi项目听起来是获取程序集列表的一个更好的选择。谢谢,gacapi(fusion.dll)是我所需要的:)剩下的我都有了。
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));