2011-02-07 28 views
8

Sto utilizzando lo Activator per creare un'istanza di una nuova classe basata sul nome breve di un assembly (ad es. "CustomModule"). Getta un FileNotFoundException, perché l'assemblea non è lì. C'è un modo per verificare se è presente un determinato nome assembly?Come verificare se esiste un determinato assemblaggio?

Sto utilizzando il seguente codice:

System.Runtime.Remoting.ObjectHandle obj = 
    System.Activator.CreateInstance(assemblyName, className); 

L'obiettivo principale è quello di testare piuttosto per la presenza del gruppo piuttosto che aspettare che l'eccezione si verifichi.

+0

Vuoi dire caricato nel dominio dell'app corrente? Cos'è 'assemblyName'? Un nome assembly completo o un percorso file fisico? –

+0

@MrDisaapointment l'unica cosa che so è che ho un "CustomModule" nel mio database. Se un CustomModule.dll è presente nel mio cestino o GAC (!?) Di quanto non produrrà la classe specificata da classname. –

+0

Vedere il mio ultimo aggiornamento, si spera che questo sia sufficiente per andare avanti. –

risposta

8

Se noterai il mio commento alla tua domanda sarà evidente che non sono giustamente sicuro esattamente di come vuoi o devi fare questo, ma finché non avremo una descrizione più elaborata posso solo offrire questo nella speranza che si adatta bene alla vostra situazione (la chiave è nella 'ricerca' le assemblee):

var className = "System.Boolean"; 
var assemblyName = "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; 
var assemblies = AppDomain.CurrentDomain.GetAssemblies(); 
var assembly = (from a in assemblies 
       where a.FullName == assemblyName 
       select a).SingleOrDefault(); 
if (assembly != null) 
{ 
    System.Runtime.Remoting.ObjectHandle obj = 
     System.Activator.CreateInstance(assemblyName, className);    
} 

NET 2.0 codice compatibile

Assembly assembly = null; 
var className = "System.Boolean"; 
var assemblyName = "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; 

foreach (var a in AppDomain.CurrentDomain.GetAssemblies()) 
{ 
    if (a.FullName == assemblyName) 
    { 
     assembly = a; 
     break; 
    } 
} 

if (assembly != null) 
{ 
    System.Runtime.Remoting.ObjectHandle obj = 
     System.Activator.CreateInstance(assemblyName, className); 
} 

Se si vuole determinare se il file esiste prima di provare a lo ad esso (una buona pratica), allora, data avete il suo nome e si conosce la posizione desiderata, semplicemente cercare di trovare il file quando il gruppo è stato risolto:

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

var className = "StackOverflowLib.Class1"; 
var assemblyName = "StackOverflowLib.dll"; 
var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
var obj = Activator.CreateInstance(Path.Combine(currentAssemblyPath, assemblyName), className); 

static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
{ 
    var currentAssemblyPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); 
    if (File.Exists(Path.Combine(currentAssemblyPath, args.Name))) 
    { 
     return Assembly.LoadFile(Path.Combine(currentAssemblyPath, args.Name)); 
    } 
    return null; 
} 
+0

@MrDisappointment, grazie per il codice Non sono riuscito a specificare che sto lavorando in .Net 2.0 –

+1

Questo non restituisce solo gli assembly già caricati nell'AppDomain? – mmix

+0

@mmix ha un punto valido. Potrei avere una dll presente nella directory bin che non è stata caricata. –

1

Il gruppo mancante costituisce un'eccezione, prova/cattura FileNotFoundException e gestisce la situazione secondo la logica.

+0

100% vero! Ma mi piacerebbe testarlo, piuttosto che aspettare che si verifichi l'eccezione. –

+0

In cima alla mia testa, non penso che lo gestirai facilmente poiché dovrai emulare un algoritmo di verifica completo. È anche soggetto a errori (dovrebbe dire che il dominio dell'applicazione installa il proprio processo di analisi). Per un primo sguardo, se vuoi ancora questo, controlla questo link: [Come il runtime individua gli assembly]: http://msdn.microsoft.com/en-us/library/yx7xezcf.aspx – mmix

2

penso che sia meglio non cercare di evitare l'eccezione. La ragione è che se si dispone di un codice simile

if (DoesAssemblyExist(asmName)) { 
    object = Activator.CreateInstance(typeName); 
} 
else { 
    MessageBox.Show("Assembly does not exist"); 
} 

c'è sempre un rischio in un sistema operativo multitasking pre-emptive che potrebbe essere aggiunto il montaggio/rimosso tra il controllo e la creazione vera e propria. Sì, mi rendo conto che questo rischio è minimo, ma continuo a pensare che la variante dell'eccezione sia migliore perché è atomica.

-1

spero che vi aiuterà per qualcuno in futuro:

Su ogni dll esterno che si sta utilizzando, creare la propria chiave uniqe, in questo modo: tasto

stringa = "fjrj3288skckfktk4owoxkvkfk4o29dic";

E poi, quando si carica il modulo, per ogni singola DLL esterna che avete ottenuto, è sufficiente verificare se la chiave è esiste in questo modo:

Se (chiave isMyLib.Variables.key ==) // continua

else // .dll non esiste o non è rotto.

Problemi correlati