Здравствуйте, Grammer, Вы писали:
G>Вопрос: G>Как изменить путь поиска при загрузки dll и её последующем использовании
G>то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов G>а исполняемая среда ищет почему то только в основной папке приложения...
G>изменение CurrentDirectiory не помогло
Знаю способ. Очень хорошо помогает.
AppDomain.AppendPrivatePath(string path)
не помню точно как надо путь указывать относительно basedirectory или абсолютный.
проходит нормально
а вот при потытке сделать что либо с depExpLib.dll например как в моем примере получить тип который написан на базе типа из expLib.dll то вылетает FileNotFoundException c ошибкой о том что не найдена expLib.dll, хотя я её до этого явно загрузил в домен...
я так понял что при попыте дотупа к типу из depExpLib.dll который написан на базе типа из expLib.dll среда вытается загрузить expLib.dll не проверяя его наличия в домене и ищет только с папке с исполняемым модулем не заходя в папку Plugins
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting app");
Program p = new Program();
p.Run();
Console.WriteLine("Exiting app. Press enter to exit");
Console.ReadLine();
}
public Program()
{
}
public void Run()
{
LoadPlugins();
}
public void LoadPlugins()
{
List<Assembly> asmList = new List<Assembly>();
asmList.Add(Assembly.LoadFile(Environment.CurrentDirectory + "\\Plugins\\depExpLib.dll"));
asmList.Add(Assembly.LoadFile(Environment.CurrentDirectory + "\\Plugins\\expLib.dll"));
//Environment.CurrentDirectory += "\\Plugins"; // не помогаетforeach (Assembly asm in asmList)
{
try
{
Type[] types = asm.GetExportedTypes(); // вот тут Binding Failure Exceptionforeach (Type type in types)
{
Console.WriteLine(type.ToString());
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
}
}
Exception
BindingFailure was detected
Message: The assembly with display name 'expLib' failed to load in the 'Anonymous' binding context of the AppDomain with ID 1. The cause of the failure was: System.IO.FileNotFoundException: Could not load file or assembly 'expLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. Не удается найти указанный файл.
File name: 'expLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
=== Pre-bind state information ===
LOG: User = SIS_DOMAIN\Strakh_a
LOG: DisplayName = expLib, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
(Fully-specified)
LOG: Appbase = file:///D:/My_Project/OTHER/Копия AppDomainAsm/AppDomainAsm/bin/Release/
LOG: Initial PrivatePath = NULL
Calling assembly : (Unknown).
===
LOG: This bind starts in default load context.
LOG: No application configuration file found.
LOG: Using machine configuration file from C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config.
LOG: Policy not being applied to reference at this time (private, custom, partial, or location-based assembly bind).
LOG: The same bind was seen before, and was failed with hr = 0x80070002.
Всем спасибо!
Загрузка библиотек и путь их поиска...
От:
Аноним
Дата:
03.04.06 10:48
Оценка:
Перед тем, как загружать assemblies, подпишитесь на событие AppDomain.AssemblyResolve вот так:
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.AssemblyResolve += new ResolveEventHandler(OnAssemblyResolveEventHandler);
try
{
// вставьте Ваш кодЮ который грузит assemblies и классы сюда.
}
finally
{
currentDomain.AssemblyResolve -= new ResolveEventHandler(OnAssemblyResolveEventHandler);
}
private Assembly OnAssemblyResolveEventHandler(object sender, ResolveEventArgs args)
{
// каждый раз, когда framework не может найти assembly, он вызывает это событие — укажите правильный путь к assembly здесь
}
Вопрос:
Как изменить путь поиска при загрузки dll и её последующем использовании
то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов
а исполняемая среда ищет почему то только в основной папке приложения...
изменение CurrentDirectiory не помогло
Re[2]: Загрузка библиотек и путь их поиска...
От:
Аноним
Дата:
03.04.06 13:26
Оценка:
В обработчике события OnAssemblyResolveEventHandler в параметре
ResolveEventArgs args находится имя assembly, которое framework не смог загрузить. Вам надо, зная имя этой assembly, загрузить ее в AppDomain.
Смотрите документацию по AppDomain.AssemblyResolve Event в MSDN. Там есть примеры, как это сделать.
Здравствуйте, Grammer, Вы писали:
G>Вопрос: G>Как изменить путь поиска при загрузки dll и её последующем использовании
G>то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов G>а исполняемая среда ищет почему то только в основной папке приложения...
G>изменение CurrentDirectiory не помогло
Вообщем воспользовался я (ради любопытсва) функцией LoadFrom которую настоятельно не рекомендуют использовать mcrosofterы так как это может привести к ошибкам, и о чюдо — нашлась и рядом лежащая сборка указанная в референсах
но попрос остается открытым так как ребята из microsoft настоятельно не рекомендуют использовать функцию LoadFrom а пользоваться функцией LoadFile при этом кладя сборку в "appBase or GAC"
очень хорошо помогает?? да это единственный привильный способ!
огромное спасибо
S>AppDomain.AppendPrivatePath(string path) S>не помню точно как надо путь указывать относительно basedirectory или абсолютный.
да и еще сейчас AppendPrivatePath obsolete и рекуомендуют
не знаю почему не рекомендуют использовать AppendPrivatePath ведь она по сути лишь добавляет в вышеупомянутое проперти путь...
Re[5]: Загрузка библиотек и путь их поиска...
От:
Аноним
Дата:
05.04.06 08:06
Оценка:
Здравствуйте, Grammer, Вы писали:
S>>Знаю способ. Очень хорошо помогает.
G>очень хорошо помогает?? да это единственный привильный способ! G>огромное спасибо
S>>AppDomain.AppendPrivatePath(string path) S>>не помню точно как надо путь указывать относительно basedirectory или абсолютный.
G>да и еще сейчас AppendPrivatePath obsolete и рекуомендуют G>
В> // Find the name of this assembly and load it into the domain В> string assemblyName = Assembly.GetExecutingAssembly().FullName; В> domain.Load(assemblyName);
В этом месте у меня под Net2.0 вываливается в Exception (хотя в 1.1 работает)
System.Security.SecurityException was unhandled
Message="Request for the permission of type 'System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed."
Source="mscorlib"
GrantedSet="<PermissionSet class=\"System.Security.PermissionSet\"\r\nversion=\"1\">\r\n<IPermission class=\"System.Security.Permissions.FileDialogPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAccess=\"Open\"/>\r\n<IPermission class=\"System.Security.Permissions.IsolatedStorageFilePermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nAllowed=\"ApplicationIsolationByUser\"\r\nUserQuota=\"512000\"/>\r\n<IPermission class=\"System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nFlags=\"Execution\"/>\r\n<IPermission class=\"System.Security.Permissions.UIPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nWindow=\"SafeTopLevelWindows\"\r\nClipboard=\"OwnClipboard\"/>\r\n<IPermission class=\"System.Security.Permissions.SiteIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nSite=\"tempuri.org\"/>\r\n<IPermission class=\"System.Security.Permissions.StrongNameIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nPublicKeyBlob=\"0000000000000000\"\r\nName=\"Spe.application\"\r\nAssemblyVersion=\"1.0.0.0\"/>\r\n<IPermission class=\"System.Security.Permissions.UrlIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nUrl=\"http://tempuri.org/Spe.application\"/>\r\n<IPermission class=\"System.Security.Permissions.ZoneIdentityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nZone=\"Internet\"/>\r\n<IPermission class=\"System.Drawing.Printing.PrintingPermission, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a\"\r\nversion=\"1\"\r\nLevel=\"SafePrinting\"/>\r\n<IPermission class=\"System.Net.WebPermission, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\">\r\n<ConnectAccess>\r\n<URI uri=\"(http|https)://tempuri\\.org/.*\"/>\r\n</ConnectAccess>\r\n</IPermission>\r\n</PermissionSet>\r\n"
PermissionState="<IPermission class=\"System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089\"\r\nversion=\"1\"\r\nFlags=\"ControlEvidence\"/>\r\n"
RefusedSet=""
Url=""
StackTrace:
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessPermission.Demand()
at System.Reflection.Assembly.InternalLoad(AssemblyName assemblyRef, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.Reflection.Assembly.InternalLoad(String assemblyString, Evidence assemblySecurity, StackCrawlMark& stackMark, Boolean forIntrospection)
at System.AppDomain.Load(String assemblyString, Evidence assemblySecurity)
at System.AppDomain.Load(String assemblyString, Evidence assemblySecurity)
at SPE.PluginManager.LoadPluginTypes(PluginTrustLevel level, PluginCriteria criteria, Type criteriaType) in D:\Projects\Spe2007\SPE\PluginManager.cs:line 63
at SPE.MainForm.LoadPlugIns(Object data) in D:\Projects\Spe2007\SPE\MainForm.cs:line 310
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
Здравствуйте, Grammer, Вы писали:
G> ... да это единственный привильный способ!
Отнюдь. Это всего-то возможность конфигурирования приложения в рантайме. Изначально все решается весьма просто: в конфигурационном файле вашего приложения необходимо было добавить элемент <probing>, примерно так:
privatePath указывает подкаталоги, относительно корневого каталога приложения, в которых CLR может попытаться найти сборки. Разделются подкаталоги точками с запятыми (см. пример).
Если редактировать конифгурационный файл текстовым редактором не по душе — обратите внимание на конфигурационные утилиты (Панель управления -> Администрирование -> Microsoft .NET Framever 5.0 Configuration ( ) ) — выбираете свое приложение, и конфигурите, конфигурите, конфигурите...
G>не знаю почему не рекомендуют использовать AppendPrivatePath ведь она по сути лишь добавляет в вышеупомянутое проперти путь...
Просто предположение. Может, потому, что она не CLS компилант, и, чисто идеологически, ее использовать грешно.