Résoudre les références d'assembly à partir d'un autre dossier
Je développe une application qui référence et utilise un tiers des assemblages à partir d'un certain Fournisseur; dans le développement de la boîte, j'ai ces 3 sous-ensembles dans un dossier de référence dans mon arbre source et je peut faire référence à eux et de construire l'application, l'application s'appuie, mais ne fonctionne pas parce que l'ensemble de l'application serveur n'est pas installé, mais c'est très bien.
Sur le serveur où je veux copier cette application personnalisée et exécuter toutes les assemblées, je suis le référencement sont dans le dossier quelque chose comme:
D:\ProgramFiles\VendorName\ProductName\Support\API\Bin64
et si je copie mon petit exécutable dans le dossier et l'exécuter, il fonctionne parfaitement, mais si je mets mon .exe dans un plus dossier approprié comme je veux:
D:\ProgramFiles\MyCompanyName\MyProduct\bin\...
il ne fonctionne pas car il ne peut pas résoudre ces assemblées.
Je sais que je peux utiliser de palpage dans l'app.config pour spécifier les dossiers de mon exe a trouver les références, mais imy cas, les assemblées ne sont pas dans un sous-dossier, de plus en plus dans un tout autre endroit.
Je ne veux pas copier tous les fournisseurs assemblées dans mon dossier app et je ne peux pas mettre seulement la 3 je suis référencement parce qu'ils sont aussi charger d'autres assemblées et à moins que je les ai tous (beaucoup...), il ne fonctionne pas.
Je ne fais pas quelque chose de spécial, pas de création d'application les domaines et pas de chargement des assemblages par réflexion, je veux juste le CLR pour résoudre les références car ils sont nécessaires au démarrage de l'application ou de l'exécution.
Grâce.
Edit: voici le dernier code de travail
static System.Reflection.Assembly currentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Logger logger = new Logger();
try
{
string RMSAssemblyFolder = ConfigurationManager.AppSettings["RMSAssemblyFolder"];
Assembly MyAssembly = null;
string strTempAssmbPath = string.Empty;
Assembly objExecutingAssemblies = Assembly.GetExecutingAssembly();
AssemblyName[] arrReferencedAssmbNames = objExecutingAssemblies.GetReferencedAssemblies();
AssemblyName myAssemblyName = Array.Find<AssemblyName>(arrReferencedAssmbNames, a => a.Name == args.Name);
if (myAssemblyName != null)
{
MyAssembly = Assembly.LoadFrom(myAssemblyName.CodeBase);
}
else
{
strTempAssmbPath = Path.Combine(RMSAssemblyFolder, args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll");
if (!string.IsNullOrEmpty(strTempAssmbPath))
{
if (File.Exists(strTempAssmbPath))
{
logger.Information("Assembly to load: {0} - File was found in: {1}", args.Name, strTempAssmbPath);
//Loads the assembly from the specified path.
MyAssembly = Assembly.LoadFrom(strTempAssmbPath);
}
}
}
//Returns the loaded assembly.
return MyAssembly;
}
catch (Exception exc)
{
logger.Error(exc);
return null;
}
}
OriginalL'auteur Davide Piras | 2011-03-10
Vous devez vous connecter pour publier un commentaire.
Vous devez d'abord trouver le dossier où les thèses de dll sont installés ensuite utiliser
domaine d'application.AssemblyResolve
à crochet résolution de l'assemblée et essayer de le charger à la demande des assemblages à partir de ce dossier.Il ressemblera à quelque chose comme ça (pas testé, et vous avez besoin de vérifier ce
args.Name
contiennent exactement, pourrait contenir la version et le nom fort avec nom du type) :Sûrement ma solution peut être optimisé, je ne sais pas si cette méthode doit retourner la valeur null si l'assemblée n'est pas trouvé dans le dossier personnalisé et, dans l'affirmative, le CLR vais encore chercher dans le GAC, parce que par exemple, j'ai remarqué que cette méthode est également appelée pour les assemblées comme Système.XML.Sérialiseur... je suis en train de tester cela dans une application console qui accueille un netTcp lié Service WCF, maintenant ça fonctionne et que je puisse exécuter l'application à partir de n'importe quel dossier, en fin de compte, je vais créer une WindowsService pour héberger mon WCF. Merci Encore Une Fois .))
Coo, merci. Vais essayer cela dans quelques jours.
J'ai trouvé que cette approche ne fonctionne pas pour moi. De l'assemblée.Load() avec un chemin d'accès complet échoue; il appelle la AssemblyResolve une fois de plus (car il ne peut pas résoudre la DLL). Donc, je suis actuellement à la recherche dans l'aide de l'Assemblée.LoadFrom() à l'intérieur de la AssemblyResolve gestionnaire de la place.
'var dll = otherCompanyDlls.FirstOrDefault(fi => fi gratuite.Nom == args.Nom de la personne) - les causes de la lienear analyse de la liste à chaque coup ou manquer. Avec un grand nombre oaf demandé et des assemblages existants peut être un problème de performance.
OriginalL'auteur Julien Roncaglia
Utilisation SN.exe : SN -T VendorAssembly.dll ce sera le retour d'un nombre hexadécimal qui est le jeton de clé publique, puis, en référence à l'assembly à partir de l'app.config. Pour obtenir la version de droite, cliquez sur votre fournisseur d'assemblage et de les utiliser pour la base de code de la version de la valeur, de href=chemin d'accès que vous avez mentionné.
OriginalL'auteur kd7