/ / GetExportedTypes () FileNotFoundException: impossibile trovare l'assembly - c #, filenotfoundexception

GetExportedTypes () FileNotFoundException: impossibile trovare l'assembly - c #, filenotfoundexception

Il mio compito: Trova tutti i moduli (WindowsForm o WPF, non importa) in un file dll o exe e restituire quell'elenco. In teoria funziona (ovvero: se ho un assembly con un WPF o WindowsForm il mio codice riesce a ottenere tutti i moduli, Caselle di testo, etichette, ecc.). Quando si tratta di assemblaggi "reali", fallisce. Ottengo eccezioni FileNotFound quando si chiama GetExportedTypes () per ogni assembly "personalizzato" (vengono trovati assembly .NET, nessun problema). Utilizzo già GetReferencedAssemblies () per caricare gli assembly di riferimento (Reflection.Assembly.LoadFrom) e sì funziona (tutti gli assembly vengono trovati e caricati nell'AppDomain) ma non aiuta.

Ho controllato i numeri di versione (corrispondono), ho copiato il mio eseguibile e l'assembly in una directory con tutti gli assembly di riferimento, non funziona.

Ecco il mio codice, forse qualcuno capisce cosa sto facendo (ovviamente) sbagliato:

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();
}

per prima cosa controlla se esiste la DLL di riferimentola directory in cui si trova l'assembly, se non controlla se esiste in C: dll e se non è lì prova e usa GAC. Funziona e non ho errori da lì ma non appena arrivo a GetExportedTypes fallisce con un'eccezione FileNotFound sulla prima libreria personalizzata.

* modifica 1 cosa intendo per "assiemi reali": intendo assiemi più complessi e riferimenti a librerie / assiemi non standard-.NET


Grazie per il suggerimento a fuslogvw.exe Hans Passant ma cosa intendi con "con codice come questo"?


okay ho usato fuslogvw.exe e ottengo due eccezioni per ogni singola DLL a cui fa riferimento "selectedAssembly". Il primo dice qualcosa del genere "L'associazione inizia in LoadFrom-context L'immagine di proprietà del sistema non viene cercata in LoadFrom-Context "

l'altro logentry dice che la DLL ha fatto riferimentodall'assembly selezionato non è stato possibile trovarlo e ha provato a scaricarlo dal percorso di base dell'applicazione e da tutte le directory in basso ... ma non dalla sua posizione effettiva ... quindi, domanda chiave: come cambio il carico- contesto a LoadFrom? E perché .NET è così testardo su questo? Voglio dire che gli assembly sono caricati nell'AppDomain, non dovrebbe preoccuparsi della posizione effettiva dell'assembly.


ok problema risolto. Ecco la soluzione: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

L'ho implementato nella mia classe esistente (rimosso la parola chiave static e inserito il corpo del metodo Init nel mio metodo), l'ho compilato e ha funzionato.

Grazie per il vostro aiuto ragazzi.

risposte:

4 per risposta № 1

ok problema risolto. Ecco la soluzione: http://ayende.com/blog/1376/solving-the-assembly-load-context-problem

L'ho implementato nella mia classe esistente (rimosso la parola chiave static e inserito il corpo del metodo Init nel mio metodo), l'ho compilato e ha funzionato.

Grazie per il vostro aiuto ragazzi.

nel caso in cui un giorno il sito Web non sarà disponibile, ecco il codice sorgente di 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 per risposta № 2

Consiglierei l'uso di Reflector per vedere qualeriferimenti che potresti non aver caricato. Ad esempio, si stanno caricando solo gli assembly di riferimento che l'assembly corrente sta esaminando. Scendete attraverso ogni bambino per trovare anche i loro assembly referenziati? L'errore FileNotFound probabilmente ti sta indicando nella direzione di un tipo dichiarato in un altro assembly che non è stato caricato.