8
votes

Comment vérifier si une certaine assemblée existe?

J'utilise l'activateur pour instancier une nouvelle classe en fonction du nom abrégé d'un assemblage (E.A. 'Custommoundue'). Il jette un FilenotFoundException , car l'assemblage n'est pas là. existe-t-il un moyen de vérifier si un certain nom de montage est présent?

J'utilise le code suivant: xxx

L'objectif principal doit plutôt tester la présence de l'ensemble que d'attendre que l'exception se produise.


5 commentaires

Vous voulez dire chargé dans le domaine d'application actuel? Qu'est-ce que AssemblyName ? Un nom de montage entièrement qualifié ou un chemin de fichier physique?


@MRDisaApointment La seule chose que je sais, c'est que j'ai un "Customagnole" dans ma base de données. Si un Tempsommeux.dll est présent dans ma corbeille ou GAC (!?) Qu'il ne produira la classe spécifiée par nom de classe.


Voir ma dernière mise à jour, j'espère que cela suffit à continuer.


HM ... La méthode .NET 1.1 utilise Assembly.LoadWithPartialName qui retournera «null» si l'assemblage n'est pas présent.


(?) Oui, si l'assemblage n'est pas présent, alors vous obtenez null , mais vous avez déjà fait toutes les vérifications que vous pouvez (en supposant que vous ayez adopté le code dans ma réponse), alors est donc le temps Pour obtenir le FilenotfoundException .


4 Réponses :


1
votes

Assembly manquant constitue définitivement une exception, essayez / attraper filenotfoundexception et gérer la situation selon votre logique.


2 commentaires

100% vrai! Mais je voudrais tester pour cela, plutôt que d'attendre que l'exception se produise.


Sur le dessus de ma tête, je ne pense pas que vous gérez facilement cela, car vous devez imiter un algorithme de sondage complet. C'est également sujet à des erreurs (devrait dire que le domaine d'application installe son propre processus de sondage). Pour un premier look d'arrêt, si vous le souhaitez toujours, cochez ce lien: [Comment l'exécution localise les assemblages]: msdn.microsoft.com/en-us/library/yx7xezcf.aspx



10
votes

Si vous remarquerez mon commentaire à votre question, il sera évident que je ne suis pas à juste titre sûr comment em> vous voulez ou devez y aller, mais jusqu'à ce que nous ayons une description plus élaborée Je peux seulement vous offrir cela dans l'espoir qu'il convient à votre situation (la clé est dans la recherche des assemblages):

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


9 commentaires

@MRDisAppointment, merci pour le code. Je n'ai pas spécifié que je travaille dans .net 2.0


Ce retour ne renvoie-t-il pas que des assemblages déjà chargés dans l'AppDomain?


@mmix a un point valide. Je pourrais avoir une DLL présentée dans le répertoire bin qui n'a pas été chargée.


Je suis d'accord, comme je l'ai dit dans ma réponse et commentaire: comment exactement tu voulais faire cela était incertain, alors je n'avais pas beaucoup de choses à parcourir.


HM ... La méthode .NET 1.1 utilise Assembly.LoadWithPartialName qui retournera «null» si l'assemblage n'est pas présent.


(?) Oui, si l'assemblage n'est pas présent, alors vous obtenez null , mais vous avez déjà fait toutes les vérifications que vous pouvez (en supposant que vous ayez adopté le code dans ma réponse), alors est donc le temps Pour obtenir le FilenotfoundException .


Cela semble fonctionner. Parce que je ne connais pas le nom complet (seulement le nom partiel), j'utilise: si (a.fullname.contains (partielName)). Je n'ai aucune idée de savoir si cela tiendra.


J'ai essayé l'exemple AssemblyResolve, mais celui-ci n'est pas appelé mon système. Je reçois le message "Le nom de montage donné ou la base de code n'était pas valide. (Exception de HRESULT: 0x80131047) '. J'utiliserai l'exemple de .NET 2.0 car cela fonctionne mieux pour ma situation.


La méthode AssemblyResolve doit fonctionner comme conçue comme conçue - je ne sais pas ce qui se passe là-bas. Une note peut être de transmettre uniquement le nom de fichier dll sur CreateInstance et construire le chemin complet dans le AssemblageResolve gestionnaire d'événements.



2
votes

Je pense qu'il vaut mieux ne pas essayer d'éviter l'exception. La raison en est que si vous avez du code comme xxx

, il existe toujours un risque dans un système d'exploitation multitâche préventif que l'ensemble peut être ajouté / retiré entre la vérification et la création réelle. Oui, je me rends compte que ce risque est minime, mais je pense toujours que la variante d'exception semble meilleure car elle est atomique.


0 commentaires

-1
votes

J'espère que cela aidera à quelqu'un à l'avenir:

sur chaque externe .dll que vous utilisez, créez sa propre clé UNIQE, comme:

clé de chaîne = "fjrj3288skckfktk4owoxkvkfk4o29dic";

et ensuite, lorsque vous chargez votre formulaire, pour chaque externe .dll que vous avez obtenu, vérifiez simplement si la clé est existez comme si:

si (ismylib.variables.key == clé) // Continuer

autre // .dll n'existe ni cassé.


0 commentaires