Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scanning DLLs for .NET assemblies with a particular interface - some DLLs throw R6034!

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?]

like image 825
Joe Avatar asked Feb 17 '11 21:02

Joe


2 Answers

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.

like image 106
Ben Voigt Avatar answered Sep 21 '22 00:09

Ben Voigt


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.

like image 29
jonathanpeppers Avatar answered Sep 21 '22 00:09

jonathanpeppers