Fichier introuvable lorsque la charge de l'assemblée de la dépendance à un autre domaine
Je suis en train de faire une application avec des plugins.
J'ai MainLib.dll, où j'ai fait quelques commnon interface(que ce soit ICommon
) avec la méthode 1. Ensuite, j'ai fait les 2 .dll(plugins) qui font référence à MainLib.dll et de mettre en œuvre la ICommon
dans certaines classes. Aussi, j'ai supprimé toutes les références dans le présent .dll exepté System
.
Ensuite, j'ai créé une application qui surveille dossier ".\\Plugins"
et charges de tous .dll dans newDomain
, vérifier si les types en .dll en œuvre ICommon
(donc cette application également référence à MainLib.dll). Si oui - ajouter le nom de .dll dans certains liste.
Et maintenant, voici le problème:
avant j'ai essayé de charger les plugins - je charger MailLib.dll et le Système newDomain parce que tous les plugins de dépendance .les dll. Ils ont la charge correcte. Puis, je commence à charger des plugins, et là j'ai:
FileNotFoundException, impossible de charger le fichier ou l'assembly 'PluginWithException, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' ou une de ses dépendances. Le système ne peut pas trouver le fichier spécifié.) sur la chaîne d'Assemblage loadedAssembly = domaine.De La Charge(De L'Assemblée.LoadFrom(asm).FullName);
PluginWithException assemblée n'en a que 2 de dépendance au Système et MainLib. Avant que je tryied pour charger PluginWithException j'ai vérifié assemblées dans un nouveau domaine, de Système et de MainLib ont été chargés de ce domaine. Donc je ne peux pas voir tout ploblems de la dépendance. J'ai lu cette sujet, et a essayé la solution avec ProxyDomain
mais l'exception est la même.
Ce que je fais mal?
Voici le code:
public static List<string> SearchPlugins(string[] names)
{
AppDomain domain = AppDomain.CreateDomain("tmpDomain");
domain.Load(Assembly.LoadFrom(@".\MainLib.dll").FullName);
domain.Load(@"System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
MessageBox.Show(GetAssembies(domain)); //here I can see that System and MailLib exist in new domain
List<string> plugins = new List<string>();
foreach (string asm in names)
{
Assembly loadedAssembly = domain.Load(Assembly.LoadFrom(asm).FullName); //here I have exception
var theClassTypes = from t in loadedAssembly.GetTypes()
where t.IsClass &&
(t.GetInterface("ICommonInterface") != null)
select t;
if (theClassTypes.Count() > 0)
{
plugins.Add(asm);
}
}
AppDomain.Unload(domain);
return plugins;
}
OriginalL'auteur Dima Serdechnyi | 2013-05-04
Vous devez vous connecter pour publier un commentaire.
vous ne précisez pas la façon dont vous êtes en train de configurer votre recherche de chemins d'accès pour vos domaines d'application afin qu'il puisse trouver la Dll dans le répertoire Plugins, toutefois votre problème sonne comme il pourrait être très semblable à celui-ci j'ai répondu hier:
Domaine d'application.Load() échoue avec l'erreur FileNotFoundException
Peut-être est ce aussi de résoudre votre problème? Laissez-moi savoir comment vous vous y prenez.
var plugins = loader.LoadPlugins( Assembly.LoadFrom(Environment.CurrentDirectory + @"\Plugins\PluginWithOutException.dll").FullName);
mais ça ne l'aide pas:( La seule exception est le même:(Avez-vous essayez de configurer une PrivateBinPath pour l'enfant domaine d'application lors de la création, de sorte qu'il sait à rechercher dans le dossier Plugins bof assemblées?
var appDomainSetup = new AppDomainSetup { PrivateBinPath = "Plugins" }; var domain = AppDomain.CreateDomain("tmpDomain", AppDomain.CurrentDomain.Evidence, appDomainSetup);
Merci!!!! J'ai essayé la solution avec
PrivateBinPath
plus tôt, mais je l'ai fait de mal. Maintenant, elle se charge et fonctionne très bien. Mais, après je charge assemblées dans de nouveaux domaines, l'interface appel de la méthode et de décharger les domaines, j'ai vérifié, les assemblées de courant(par défaut) de domaine. Et malheureusement, ils ont été chargés en courant(par défaut) de domaine. Et la solution avec l'application.config sans Chargeur charge également des assemblées de domaine par défaut. Est-il vraiment possible de ne pas charger ce assemblées dans le domaine par défaut?J'ai utilisé AssemblyLoad(), c'est pourquoi des assemblages chargés de domaine par défaut. Après j'ai essayé AssemblyName.GetAssemblyName() comme dans l'exemple que vous avez donné, et tous les travaux correct, juste comme je veux! Il n'y a pas de plugin assemblées dans le domaine par défaut! Merci beaucoup!
Super, content que tout s'est bien passé pour vous!
OriginalL'auteur James Thurley
Vous pouvez dire le domaine dans lequel charger vos assemblées à partir de:
AppDomain domain = AppDomain.CreateDomain("tmpDomain", null, new AppDomainSetup { ApplicationBase = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins") });
Cependant, je ne vois pas pourquoi vous êtes le chargement des assemblages en courant (par défaut) domaine et de la tmpDomain.
OK - mais quand vous faites
Assembly.LoadFrom(asm)
il se charge dans le domaine actuel. Cela va à l'encontre de votre objectif. Je vous suggère d'avoir unPluginLoader
classe personnalisée et de la charge de cette catégorie dans la tmpDomain. Ensuite, vous pouvez écrire le code de cette classe à charger tous les plugins à l'aide deAssembly.LoadFrom
et vous retourner une liste de plugin que vous souhaitez.à l'aide de sysinternals process explorer vous pouvez trouver ce qui est chargé dans ce domaine à tout moment.
OriginalL'auteur YK1