我有一个程序需要在其主机上发现插件DLL。
它通过枚举(相当大的)路径中的所有DLL来实现此目的。此路径包含许多内容,包括本机DLL。
foreach (var f in Directory.EnumerateFiles(@"c:\Program Files", "*.dll", SearchOption.AllDirectories))
{
try
{
var assembly = Assembly.LoadFile(f);
var types = assembly.GetTypes();
foreach (var type in types)
{
if (type.GetInterface("My.IInterface") != null)
{
plugins.Add(f);
break;
}
}
assembly = null;
}
catch (Exception e)
{
}
}
如果我的扫描程序遇到MS运行时DLL(例如,msvcm80.dll),我得到一个无法捕获的运行时错误R6034:“应用程序试图错误地加载C运行时库。”该窗口阻止程序的执行。我不想要这个DLL(显然);是否有某种方法可以在这种情况下获得优雅的错误?
[相关问:如果DLL当前没有加载到进程空间中,是否有一种有效的(例如非异常)确定DLL是否是.NET程序集的方法?]
答案 0 :(得分:10)
首先使用Assembly.ReflectionOnlyLoadFrom
进行仅反射加载。只有在程序集中找到插件后,才能使用Assembly.LoadFrom
完全加载它。
要回答您的其他问题,您可以检查该文件是否具有CLR标题。
See this post "Read CLR Header" on m.p.dotnet.framework
这些可以让你在搜索插件时避免任何异常和错误消息框。
答案 1 :(得分:2)
对于\ Program Files来说似乎不是一个好主意......有人会把恶意DLL放在那里吗?
您是否看过使用MEF?它也可能更安全一点。
有一个DirectoryCatalog将为您自动加载程序集并返回您的接口数组。
不确定您是否熟悉依赖注入或(IoC)控制反转,但您也可以使用MEF。
它包含在.Net 4.0中。