2009-07-10 9 views
2

Je développe une application .NET qui utilise la réflexion pour charger des plugins. Mes plugins sont des bibliothèques de classe C#. Le problème est que certains de mes plugins font référence à des DLL Win32 conventionnelles, et C# essaye aveuglément de charger les dépendances comme s'il s'agissait de DLL .NET.Comment charger un assembly qui référence une DLL Win32?

Voici comment je charge un plug-in:

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

Je reçois un System.BadImageFormatException avec le message suivant:

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

Comment charger un programme qui fait référence à l'ensemble des DLL Win32?

Répondre

1

Si vous avez seulement besoin de certaines fonctionnalités dans le dll, vous pouvez le faire:

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

Avez-vous essayé Assembly.LoadFile()?

Rappelez-vous que LoadFile ne charge pas les fichiers dans le contexte LoadFrom et ne résout pas les dépendances en utilisant le chemin de chargement, comme le fait la méthode LoadFrom. LoadFile est utile dans ce scénario limité car LoadFrom ne peut pas être utilisé pour charger des assemblys ayant les mêmes identités mais des chemins différents; il se chargera seule la première assemblée

1

Vous voulez quelque chose comme ce qui suit:

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. 
    } 
} 

Vous devez toujours vous assurer que vos dépendances gérées ou natives sont disponibles et ne se charge pas DLLs natives par accident. Pour les ensembles gérés peuvent avoir besoin de modifier le .net sondage chemin dans le app.config pour vous assurer qu'ils se trouvent:

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

Idéalement vous voulez mettre vos plugins dans un répertoire distinct comme appelant LoadFile sur beaucoup d'assemblées vous ne vous intéresse pas est lent et une fois que vous avez chargé un assembly dans un AppDomain vous ne pouvez pas le décharger.