проходит нормально
а вот при потытке сделать что либо с 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.
Вопрос:
Как изменить путь поиска при загрузки dll и её последующем использовании
то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов
а исполняемая среда ищет почему то только в основной папке приложения...
Здравствуйте, Grammer, Вы писали:
G>Вопрос: G>Как изменить путь поиска при загрузки dll и её последующем использовании
G>то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов G>а исполняемая среда ищет почему то только в основной папке приложения...
G>изменение CurrentDirectiory не помогло
Вообщем воспользовался я (ради любопытсва) функцией LoadFrom которую настоятельно не рекомендуют использовать mcrosofterы так как это может привести к ошибкам, и о чюдо — нашлась и рядом лежащая сборка указанная в референсах
но попрос остается открытым так как ребята из microsoft настоятельно не рекомендуют использовать функцию LoadFrom а пользоваться функцией LoadFile при этом кладя сборку в "appBase or GAC"
Здравствуйте, Grammer, Вы писали:
G>Вопрос: G>Как изменить путь поиска при загрузки dll и её последующем использовании
G>то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов G>а исполняемая среда ищет почему то только в основной папке приложения...
G>изменение CurrentDirectiory не помогло
Знаю способ. Очень хорошо помогает.
AppDomain.AppendPrivatePath(string path)
не помню точно как надо путь указывать относительно basedirectory или абсолютный.
очень хорошо помогает?? да это единственный привильный способ!
огромное спасибо
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>
Перед тем, как загружать 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 здесь
}
В обработчике события OnAssemblyResolveEventHandler в параметре
ResolveEventArgs args находится имя assembly, которое framework не смог загрузить. Вам надо, зная имя этой assembly, загрузить ее в AppDomain.
Смотрите документацию по AppDomain.AssemblyResolve Event в MSDN. Там есть примеры, как это сделать.
В> // 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 компилант, и, чисто идеологически, ее использовать грешно.