Comportement étrange lors du mélange de chargement d'assemblages avec Assembly.LoadFrom et Assembly.Load

StackOverflow https://stackoverflow.com/questions/416468

  •  03-07-2019
  •  | 
  •  

Question

Comportement étrange lors du mélange de chargement d'assemblys avec Assembly.LoadFrom et Assembly.Load

J'ai rencontré un comportement étrange lors du chargement d'assemblages avec Assembly.LoadFrom, puis ultérieurement avec Assembly.Load.
Je charge un assembly à l'aide de Assembly.LoadFrom, où l'assembly est situé dans un dossier qui n'est pas le dossier d'exécution.

Plus tard dans mon code de test, lorsque j'essaye de charger à nouveau cet assembly avec Assembly.Load, le chargement échoue avec une exception System.IO.FileNotFoundException («Impossible de charger le fichier ou l'assembly…»), alors que l'assembly est déjà chargé. Le chargement échoue à la fois avec le nom fort et le nom non fort (la raison originale pour charger à nouveau cet assemblage est l'utilisation d'un format binaire).

Toutefois, si l'assembly se trouve dans le dossier d'exécution, le chargement ultérieur aboutit dans les deux cas, avec le nom fort et le nom non fort. Dans ce cas, vous pouvez voir que deux assemblages identiques sont chargés à partir de deux emplacements différents.

Un exemple de code simple qui recrée ce problème -

Assembly assembly1 = Assembly.LoadFrom (@ "C: \ a.dll");

// Le chargement avec un nom fort échoue Assembly assembly2 = Assembly.Load (@ " a, version = 1.0.0.0,       Culture = neutre, PublicKeyToken = 14986c3f172d1c2c ");

// échec du chargement également avec un non-fort Assembly assembly3 = Assembly.Load (@ "" a ");

  1. Vous expliquez pourquoi le CLR ignore l'assemblage déjà chargé?
  2. Avez-vous une idée de ce que je peux faire pour résoudre ce problème?

Merci.

Était-ce utile?

La solution

Ce n'est pas bizarre. Conformément à la documentation, le chargement avec Load et LoadFrom placera les assemblys dans différents contextes. Ceci pourrait aider.

  
      
  1. Vous expliquez pourquoi le CLR ignore l'assemblage déjà chargé?
  2.   

Parce qu'ils se trouvent dans un contexte différent.

  
      
  1. Avez-vous une idée de ce que je peux faire pour résoudre ce problème?
  2.   

Chargez à partir du même contexte ou aidez le CLR à trouver l'assembly, peut-être en associant un gestionnaire à AppDomain.AssemblyResolve .

Alternative

Si l'emplacement à partir duquel vous chargez les assemblys est un sous-dossier sous AppDomain.BaseDirectory, vous pouvez simplement ajouter une entrée à votre App.config:

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>

http://msdn.microsoft.com/en-us/library /823z9h8w.aspx

Autres conseils

@ Kent Boogart: Cela semble être la bonne explication. Pour une explication complète, Suzanne Cook a publié ce billet de blog qui élabore un peu plus que le texte original que vous avez posté: http://blogs.msdn.com/suzcook/archive/2003 /05/29/57143.aspx

Le code suivant exploite AppDomain.AssemblyResolve -

 // register to listen to all assembly resolving attempts:
 AppDomain currentDomain = AppDomain.CurrentDomain;
 currentDomain.AssemblyResolve += new ResolveEventHandler(MyResolveEventHandler);


 // Check whether the desired assembly is already loaded
 private static Assembly MyResolveEventHandler(object sender, ResolveEventArgs args) {
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    foreach (Assembly assembly in assemblies) {
       AssemblyName assemblyName = assembly.GetName();
       string desiredAssmebly = args.Name;
       if (assemblyName.FullName == desiredAssmebly) {
           return assembly;
       }
    }

    // Failed to find the desired assembly
    return null;
 }
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top