views:

486

answers:

3

I am developing a .NET application that uses reflection to load plugins. My plugins are C# class libraries. The trouble is that some of my plugins reference conventional Win32 DLLs, and C# is blindly attempting to load the dependencies as if they were .NET DLLs.

Here is how I load a plugin:

string fileName = "plugin.dll";
Assembly.LoadFrom(fileName);

I get a System.BadImageFormatException with the following message:

Could not load file or assembly 'plugin.dll' or one of its dependencies.
The module was expected to contain an assembly manifest.

How do I programmatically load an assembly that references Win32 DLLs?

+1  A: 

If you only need some functionality from within the dll, you could do this:

  [DllImport("plugin.dll")]
  public static extern void SomeFunction();
SwDevMan81
+1  A: 

Have you tried Assembly.LoadFile()?

Please remember LoadFile does not load files into the LoadFrom context, and does not resolve dependencies using the load path, as the LoadFrom method does. LoadFile is useful in this limited scenario because LoadFrom cannot be used to load assemblies that have the same identities but different paths; it will load only the first such assembly

R N
+1  A: 

You want something like the following:

foreach (string filePath in Directory.GetFiles(path, "*.DLL"))
{
    try
    {
     _assemblies.Add(Assembly.LoadFile(filePath));
    }
    catch (FileNotFoundException)
    {
     // Attempted to load something with a missing dependency - ignore.
    }
    catch (BadImageFormatException)
    {
     // Attempted to load unmanaged assembly - ignore.
    }
}

You still need to make sure your dependencies managed or native are available and not load native DLLs by accident. For managed assemblies may need to alter the .net probing path in the app.config to make sure they are found:

<configuration>
    <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <probing privatePath="modules"/>
     </assemblyBinding>
    </runtime>

Ideally you want to put your plugins in a separate directory as calling LoadFile on lots of assemblies you're not interested in is slow and once you've loaded an assembly into an AppDomain you can't unload it.

Ade Miller