/ / GetExportedTypes () FileNotFoundException: Impossible de trouver l'assembly - c #, filenotfoundexception

GetExportedTypes () FileNotFoundException: Impossible de trouver l'assembly - c #, filenotfoundexception

Ma tâche: Trouvez tous les formulaires (WindowsForm ou WPF, peu importe) dans un fichier dll ou exe et renvoyez cette liste. En théorie, cela fonctionne (ce qui signifie: si je possède un assemblage avec WPF ou WindowsForm, mon code parvient à obtenir tous les formulaires, TextBoxes, Labels etc.). Quand il s'agit de "vrais" assemblages, cela échoue. J'obtiens des exceptions FileNotFound lors de l'appel de GetExportedTypes () pour chaque assemblage "personnalisé" (des assemblys .NET sont trouvés, aucun problème ici). J'utilise déjà GetReferencedAssemblies () pour charger les assemblys référencés (Reflection.Assembly.LoadFrom) et oui, cela fonctionne (tous les assemblys sont trouvés et chargés dans AppDomain) mais cela n’aide en rien.

J'ai vérifié les numéros de version (ils correspondent), j'ai copié mon exécutable et l'assembly dans un répertoire avec tous les assemblys référencés, cela ne fonctionne pas.

Voici mon code, peut-être que quelqu'un comprend ce que je fais (évidemment) mal:

foreach (AssemblyName reference in selectedAssembly.GetReferencedAssemblies())
{
if (System.IO.File.Exists(
System.IO.Path.GetDirectoryName(selectedAssembly.Location) +
@"" + reference.Name + ".dll"))
{
System.Reflection.Assembly.LoadFrom(
System.IO.Path.GetDirectoryName(selectedAssembly.Location) +
@"" + reference.Name + ".dll");
}
else if (System.IO.File.Exists(@"C:dll" + reference.Name + ".dll"))
{
System.Reflection.Assembly.LoadFrom(@"C:dll" + reference.Name + ".dll");
}
else
{
System.Reflection.Assembly.ReflectionOnlyLoad(reference.FullName);
}

selectedAssembly.GetExportedTypes();
}

au début, vérifiez si la DLL référencée existe dansle répertoire où se trouve l'assembly, sinon vérifiez s'il existe dans C: dll et s'il n'y est pas, essayez d'utiliser le GAC. Cela fonctionne et je "n'ai aucune erreur à partir de là, mais dès que je viens à GetExportedTypes, échoue avec une exception FileNotFound sur la première bibliothèque personnalisée.

* edit 1 ce que je veux dire par "assemblages réels": j'entends des assemblages plus complexes et référencés vers des bibliothèques / assemblages non standard-.NET


Merci pour la suggestion à Hans Passant de fuslogvw.exe mais qu'entendez-vous par "avec un code comme celui-ci"?


ok j'ai utilisé fuslogvw.exe et je reçois deux exceptions pour chaque dll unique qui est référencée par le "selectedAssembly". Le premier dit quelque chose comme "La liaison commence dans LoadFrom-context L'image appartenant au système n'est pas "recherchée dans LoadFrom-Context"

l'autre logentry dit que la dll référencéepar l \ 'assemblage sélectionné n \' a pas pu être trouvé et il a essayé de le télécharger depuis le chemin de base de l \ 'application et tous les répertoires ci-dessous ... mais pas depuis son emplacement actuel ... donc, question clé: comment changer le Et pourquoi .NET est-il si têtu à ce sujet? Je veux dire que les assemblys sont chargés dans AppDomain, il ne faut pas s’inquiéter de l’emplacement réel de l’assemblage.


ok problème résolu. Voici la solution: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

J'ai implémenté cela dans ma classe existante (j'ai supprimé le mot-clé static et mis le corps de la méthode Init dans ma méthode), je l'ai compilé et cela a fonctionné.

Merci pour votre aide les gars.

Réponses:

4 pour la réponse № 1

ok problème résolu. Voici la solution: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

J'ai implémenté cela dans ma classe existante (j'ai supprimé le mot-clé static et mis le corps de la méthode Init dans ma méthode), je l'ai compilé et cela a fonctionné.

Merci pour votre aide les gars.

juste au cas où le site Web serait un jour indisponible, voici le code source de Ayende

static Dictionary<string, Assembly>assemblies;

public static void Init()
{

assemblies = new Dictionary<string, Assembly>();

AppDomain.CurrentDomain.AssemblyLoad += new AssemblyLoadEventHandler(CurrentDomain_AssemblyLoad);

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{

Assembly assembly = null;

assemblies.TryGetValue(args.Name, out assembly);

return assembly;

}

static void CurrentDomain_AssemblyLoad(object sender, AssemblyLoadEventArgs args)
{

Assembly assembly = args.LoadedAssembly;
assemblies[assembly.FullName] = assembly;
}

2 pour la réponse № 2

Je recommanderais d'utiliser Reflector pour voir lequelréférences que vous n'avez peut-être pas chargées. Par exemple, vous ne chargez que les assemblys référencés examinés par l'assembly actuel. Est-ce que vous quittez chaque enfant pour trouver ses assemblages référencés? L’erreur FileNotFound vous indique probablement dans la direction d’un type déclaré dans un autre assembly non chargé.