I have a program that needs to discover plugin DLLs on its host.
It does this by enumerating all DLLs within a (fairly large) path. This path includes lots of things, including native DLLs.
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)
{
}
}
If my scanner hits a MS runtime DLL (for example, msvcm80.dll) I get an uncatchable runtime error R6034: "An application has made an attempt to load the C runtime library incorrectly." This window blocks execution of the program. I don't want this DLL (obviously); is there some way to get a graceful error out of this situation?
[Related q: is there an efficient (e.g. non-exception) way of determining if a DLL is a .NET assembly or not, if that DLL is not currently loaded into the process space?]
First do a reflection-only load with Assembly.ReflectionOnlyLoadFrom
. Only after you find a plugin in the assembly should you load it fully with Assembly.LoadFrom
.
To answer your other question, you can check whether the file has a CLR header.
See this post "Read CLR Header" on m.p.dotnet.framework
Together these should let you avoid any exceptions and error messageboxes while searching for plugins.
Doesn't seem like a good idea on \Program Files... Could someone put malicious DLLs in there?
Have you looked at using MEF? It might be a little safer, also.
There is a DirectoryCatalog that will auto-load assemblies for you and return you an array of your interface.
Not sure if you're familiar with Dependency Injection or (IoC) Inversion of Control, but you can use MEF for that also.
It's included in .Net 4.0.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With