Загрузка библиотек и путь их поиска...
От: Grammer  
Дата: 03.04.06 10:28
Оценка:
В продолжение темы описанной тут
Автор: Grammer
Дата: 31.03.06


Ошибка стала понятна но как с ней справиться — неясно.

Есть папка с плагинами которые пишутся как отдельно так и на основе друг друга.
Например есть два плагина:

expLib.dll
depExpLib.dll

===

которые лежат во вложенной (относительно испольняемого приложения) папке Plugins

depExpLib.dll имеет референс на expLib.dll

всяпроблема что лежат они не там же где шлавная испольняемая сборка а во вложенной папке Plugins
вообщем:

Assembly.LoadFile(Environment.CurrentDirectory + "\\Plugins\\expLib.dll");
Assembly.LoadFile(Environment.CurrentDirectory + "\\Plugins\\depExpLib.dll");


проходит нормально
а вот при потытке сделать что либо с 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 Exception
             foreach (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.


Всем спасибо!
Re: Загрузка библиотек и путь их поиска...
От: Владек Россия Github
Дата: 03.04.06 10:50
Оценка: 9 (3)
Здравствуйте, Grammer, Вы писали:

G>В продолжение темы описанной тут
Автор: Grammer
Дата: 31.03.06


G>Ошибка стала понятна но как с ней справиться — неясно.


Я всю работу с плагинами для своих приложений выдрал из этой статьи. Работает прекрасно, вот исходники:

PluginManager.cs
/// <copyright file="PluginManager.cs">
///  Copyright &copy; 2003 Jason Clark. All rights reserved.
/// </copyright>

using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.Remoting;
using System.Security;
using System.Security.Policy;
using System.Text;

namespace YourApp
{
    [Serializable]
    public enum PluginTrustLevel
    {
        Full = 1,
        Semi
    }

    [Serializable]
    public enum PluginCriteria
    {
        Interface = 1,
        BaseClass,
        CustomAttribute
    }

    public sealed class PluginManager : MarshalByRefObject
    {
        static string fullTrustPath;
        static string semiTrustPath;
        static Boolean supportSecurePlugins;

        // Path for full trust plugins
        public static string FullTrustPath
        {
            get { return fullTrustPath; }
            set { fullTrustPath = value; }
        }

        // Path for partial trust plugins
        public static string SemiTrustPath
        {
            get { return semiTrustPath; }
            set
            {
                string path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, value);
                if ((value != string.Empty) && MakeSecurePath(path))
                {
                    semiTrustPath = value;
                    supportSecurePlugins = true;
                }
                else
                {
                    supportSecurePlugins = false;
                }
            }
        }

        // Avoids instantiation by users of the class
        // also used to create an instance for cross-domain functions
        private PluginManager()
        {
        }

        // Setup default values for plugin paths
        static PluginManager()
        {
            fullTrustPath = @"Plugins\FullTrust";
            supportSecurePlugins = false;
            semiTrustPath = string.Empty;
        }

        // Get an array of plugin types using a
        // plugin criteria and trust level
        public static Type[] LoadPluginTypes(PluginTrustLevel level, PluginCriteria criteria, Type criteriaType)
        {
            // Build the path for plugins we are searching for
            // also, if secure plugins won't work, throw
            string pluginPath;
            if (level == PluginTrustLevel.Full)
            {
                pluginPath = fullTrustPath;
            }
            else
            {
                if (!supportSecurePlugins)
                {
                    throw new SecurityException(
                        "Semi-trusted plugins were not enabled!");
                }
                pluginPath = semiTrustPath;
            }

            // Create a temporary app domain so that we can unload assemblies
            AppDomain domain =
                AppDomain.CreateDomain("TempDom" + Guid.NewGuid().ToString());

            // Find the name of this assembly and load it into the domain
            string assemblyName = Assembly.GetExecutingAssembly().FullName;
            domain.Load(assemblyName);

            // Create an instance of the PluginManager type
            // in the temporary domain
            BindingFlags binding = BindingFlags.CreateInstance |
                                   BindingFlags.NonPublic | BindingFlags.Instance;
            ObjectHandle handle = domain.CreateInstance(
                assemblyName, typeof (PluginManager).ToString(), false,
                binding, null, null, null, null, null);
            PluginManager helper = (PluginManager) handle.Unwrap();

            try
            {
                // Get an array of assemblies that include matching plugins
                string[] assemblies = helper.DiscoverPluginAssembliesHelper(
                    pluginPath, criteria, criteriaType);
                // return loaded plugin types
                return LoadPluginTypesHelper(assemblies, criteria, criteriaType);
            }
            catch (ReflectionTypeLoadException)
            {
                return new Type[0];
            }
            finally
            {
                // Unload any unwanted assemblies
                AppDomain.Unload(domain);
            }
        }

        static Boolean MakeSecurePath(string path)
        {
            Boolean secure = false;
            try
            {
                // Create an Url from the path
                string url = MakePathUrl(path);
                // Get machine policy level
                PolicyLevel level = FindMachinePolicy();
                // Make sure we recognize the root code group
                CodeGroup root = level.RootCodeGroup;
                AllMembershipCondition test =
                    (AllMembershipCondition) root.MembershipCondition;
                if (!FindPluginCodeGroup(root, url))
                {
                    MakePluginCodeGroup(level, root, url);
                }
                secure = true;
            }
            catch (InvalidCastException)
            {
            }

            return secure;
        }

        static Boolean FindPluginCodeGroup(CodeGroup root, string url)
        {
            Boolean ret = false;
            // Get children
            IList children = root.Children;
            // Get name to test against
            string matchName = GenerateCodeGroupName(url);
            // Check-um all
            foreach (CodeGroup child in children)
            {
                if (child.Name == matchName)
                {
                    ret = true;
                    break;
                }
            }
            return ret;
        }

        static void MakePluginCodeGroup(PolicyLevel level, CodeGroup root, string url)
        {
            // Create a membership condition for our path
            IMembershipCondition membership =
                new UrlMembershipCondition(url);
            // Get the internet permissiion set
            PermissionSet permissions =
                level.GetNamedPermissionSet("Internet");
            permissions.GetType(); // Again, no nulls allowed
            // Create a policy statement from the permissions and condition
            PolicyStatement statement = new PolicyStatement(permissions,
                                                            PolicyStatementAttribute.Exclusive |
                                                            PolicyStatementAttribute.LevelFinal);
            // New code group
            UnionCodeGroup group = new UnionCodeGroup(membership, statement);
            group.Description = string.Format(
                "Code group that restricts permissions on " +
                "assemblies in {0}, to support secure loading of plugins. " +
                "This group was added by application: {1}", url,
                Assembly.GetEntryAssembly().CodeBase);
            group.Name = GenerateCodeGroupName(url);
            root.AddChild(group);
            SecurityManager.SavePolicyLevel(level);
        }

        // What is the name of our code group?
        static string GenerateCodeGroupName(string url)
        {
            string appName = Assembly.GetEntryAssembly().GetName().Name;
            return string.Format("{0}-{1}", appName, url);
        }

        // Get machine policy
        static PolicyLevel FindMachinePolicy()
        {
            PolicyLevel ret = null;
            // Get the policy hierarchy
            IEnumerator en = SecurityManager.PolicyHierarchy();
            en.Reset();
            // Find the policy named "Machine"
            while (en.MoveNext())
            {
                PolicyLevel level = (PolicyLevel) en.Current;
                if (level.Label == "Machine")
                {
                    ret = level;
                    break;
                }
            }

            return ret;
        }

        // Add a path to "file://" and move any back-slashes forward
        static string MakePathUrl(string path)
        {
            StringBuilder builder = new StringBuilder("file://");
            builder.Append(path);
            for (Int32 index = 0, end = builder.Length; index < end; index++)
            {
                if (builder[index] == '\\')
                    builder[index] = '/';
            }
            if (builder[builder.Length - 1] != '/')
            {
                builder.Append("/*");
            }
            else
            {
                builder.Append("*");
            }

            return builder.ToString().ToLower();
        }

        // From an array of assemblies find the plugin types
        static private Type[] LoadPluginTypesHelper(string[] assemblies,
                                                    PluginCriteria criteria, Type criteriaType)
        {
            ArrayList typesIncluded = new ArrayList();
            foreach (string s in assemblies)
            {
                // Load the assembly
                Assembly assembly = Assembly.LoadFrom(s);
                // Find the plugin types
                Type[] types = assembly.GetExportedTypes();
                foreach (Type t in types)
                {
                    if (IncludeType(t, criteria, criteriaType))
                    {
                        typesIncluded.Add(t);
                    }
                }
            }
            // Return an array of types
            return (Type[]) typesIncluded.ToArray(typeof (Type));
        }

        private string[] DiscoverPluginAssembliesHelper(string path, PluginCriteria criteria, Type criteriaType)
        {
            string[] assemblies;
            // Get .dll names
            path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
            assemblies = Directory.GetFiles(path, "*.dll");
            if (assemblies.Length != 0)
            {
                ArrayList assembliesIncluded = new ArrayList();
                foreach (string s in assemblies)
                {
                    // Load the assembly
                    Assembly assembly = Assembly.LoadFrom(s);
                    // Find matching type?
                    Type[] types = assembly.GetTypes();
                    foreach (Type t in types)
                    {
                        if (IncludeType(t, criteria, criteriaType))
                        {
                            assembliesIncluded.Add(s);
                            break; // match found, move on
                        }
                    }
                }
                // Get array of matching assemblies
                assemblies = (string[]) assembliesIncluded.ToArray(typeof (string));
            }
            return assemblies;
        }

        // Test a type for matching the plugin criteria
        private static Boolean IncludeType(Type type, PluginCriteria criteria, Type criteriaType)
        {
            Boolean judgement = false;

            // Switch on criteria type
            switch (criteria)
            {
                case PluginCriteria.Interface: // interface
                    if (!criteriaType.IsInterface)
                    {
                        throw new ArgumentException(
                            "Criteria does not match criteria type.");
                    }
                    // If compatible with the interface type, thumbs-up
                    judgement = criteriaType.IsAssignableFrom(type);
                    break;
                case PluginCriteria.BaseClass:
                    if (!(criteriaType.IsClass && !criteriaType.IsSealed))
                    {
                        throw new ArgumentException(
                            "Criteria does not match criteria type.");
                    }
                    // If compatible with the base type, thumbs-up
                    judgement = criteriaType.IsAssignableFrom(type);
                    break;
                case PluginCriteria.CustomAttribute:
                    if (!typeof (Attribute).IsAssignableFrom(criteriaType))
                    {
                        throw new ArgumentException(
                            "Criteria does not match criteria type.");
                    }
                    // If the attribute is defined on the type, then true
                    judgement = type.IsDefined(criteriaType, true);
                    break;
                default:
                    throw new ArgumentException("Invalid plugin criteria.");
            }

            return judgement;
        }

        public static Object CreateInstance(Type type, Object[] args)
        {
            try
            {
                // Calls through reflection mask exceptions in a
                // TargetInvocationException, which is annoying.
                // Un-mask by rethrowing the inner exception
                return Activator.CreateInstance(type, args);
            }
            catch (TargetInvocationException e)
            {
                throw e.InnerException;
            }
        }

        public static Object CreateInstance(Type type)
        {
            return CreateInstance(type, null);
        }
    }
}


PluginActivator.cs
using System;
using System.Collections;
using System.IO;
using System.Security;
using System.Security.Permissions;
using System.Windows.Forms;

namespace YourApp
{
    /*public*/ class PluginActivator
    {
        private Hashtable instantiatedPluginTypes;

        public delegate void EventHandler(object typeOrInstance);

        public event EventHandler TypeLoaded;
        public event EventHandler TypeInstantiated;

        public PluginActivator()
        {
            instantiatedPluginTypes = new Hashtable();
        }

        public void Load(object data)
        {
            DoLoad(PluginTrustLevel.Full);
            try {
                DoLoad(PluginTrustLevel.Semi);
            }
            catch (SecurityException) {
            }
        }

        public string[] Install(PluginTrustLevel trustLevel)
        {
            // File dialog
            OpenFileDialog dialog = new OpenFileDialog();
            dialog.Filter = "Plugin files (*.dll)|*.dll";
            dialog.FilterIndex = 1;
            dialog.RestoreDirectory = true;
            string copyToPath;
            if (trustLevel == PluginTrustLevel.Full) {
                copyToPath = PluginManager.FullTrustPath;
                dialog.Title = "Select Plugin DLL to Install Fully-Trusted";
            }
            else {
                copyToPath = PluginManager.SemiTrustPath;
                dialog.Title = "Select Plugin DLL to Install Semi-Trusted";
            }
            dialog.Multiselect = true;

            ArrayList list = new ArrayList();
            if (dialog.ShowDialog() == DialogResult.OK) {
                foreach (string dll in dialog.FileNames) {
                    string name = Path.GetFileName(dll);
                    if (!PluginAlreadyInstalled(name)) {
                        try {
                            File.Copy(dll, Path.Combine(copyToPath, name));
                            string dllConfig = dll + ".config";
                            if (File.Exists(dllConfig))
                                File.Copy(dllConfig,
                                    Path.Combine(copyToPath, name + ".config"));
                            list.Add(name);
                        }
                        catch (IOException) {
                            MessageBox.Show("Unable to install dll: " + dll, "Error");
                        }
                    }
                    else {
                        MessageBox.Show("Plugin dll already installed. To uninstall," +
                             " delete the .dll file from the Plugins directory.",
                             "Plugin Already Installed");
                    }
                }
            }
            return (string[])list.ToArray(typeof(string));
        }

        private bool PluginAlreadyInstalled(string dllFilename)
        {
            bool exists = false;
            string testFile = Path.Combine(PluginManager.FullTrustPath, dllFilename);
            exists = exists || File.Exists(testFile);
            testFile = Path.Combine(PluginManager.SemiTrustPath, dllFilename);
            exists = exists || File.Exists(testFile);
            return exists;
        }

        private void DoLoad(PluginTrustLevel level)
        {
            Type[] types;
            types = PluginManager.LoadPluginTypes(level, 
                PluginCriteria.Interface, typeof(Api.IPlugin));

            InstantiateTypes(types, instantiatedPluginTypes, true);
        }

        private void InstantiateTypes(Type[] loadedTypes, Hashtable keys, bool instantiate)
        {
            foreach (Type type in loadedTypes) {
                if (!keys.ContainsKey(type)) {
                    //TODO: add an instance of the type as a value.
                    keys.Add(type, null);
                    if (instantiate)
                        TypeInstantiated(PluginManager.CreateInstance(type));
                    else
                        TypeLoaded(type);
                }
            }
        }
    }
}


Пример использования:
// Создание папок для плагинов, если их нет.
string fullTrust = Properties.Settings.Default.FullTrustPluginPath;
string semiTrust = Properties.Settings.Default.SemiTrustPluginPath;

Directory.CreateDirectory(fullTrust);
Directory.CreateDirectory(semiTrust);

PluginManager.FullTrustPath = fullTrust;
PluginManager.SemiTrustPath = semiTrust;

// Загрузка плагинов
ThreadPool.QueueUserWorkItem(new WaitCallback(mainForm.PluginActivator.Load));

// Установка плагинов
mainForm.PluginActivator.Install(sender == installFullyTrustedToolStripMenuItem?
    PluginTrustLevel.Full: PluginTrustLevel.Semi);
// После установки, грузим новые плагины.
ThreadPool.QueueUserWorkItem(new WaitCallback(mainForm.PluginActivator.Load));
Re[2]: Загрузка библиотек и путь их поиска...
От: Grammer  
Дата: 03.04.06 12:40
Оценка:
Вопрос:
Как изменить путь поиска при загрузки dll и её последующем использовании

то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов
а исполняемая среда ищет почему то только в основной папке приложения...

изменение CurrentDirectiory не помогло
Re[3]: Загрузка библиотек и путь их поиска...
От: Grammer  
Дата: 03.04.06 14:37
Оценка:
Здравствуйте, Grammer, Вы писали:

G>Вопрос:

G>Как изменить путь поиска при загрузки dll и её последующем использовании

G>то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов

G>а исполняемая среда ищет почему то только в основной папке приложения...

G>изменение CurrentDirectiory не помогло


Вообщем воспользовался я (ради любопытсва) функцией LoadFrom которую настоятельно не рекомендуют использовать mcrosofterы так как это может привести к ошибкам, и о чюдо — нашлась и рядом лежащая сборка указанная в референсах

но попрос остается открытым так как ребята из microsoft настоятельно не рекомендуют использовать функцию LoadFrom а пользоваться функцией LoadFile при этом кладя сборку в "appBase or GAC"
Re[4]: Загрузка библиотек и путь их поиска...
От: adontz Грузия http://adontz.wordpress.com/
Дата: 04.04.06 10:41
Оценка:
Здравствуйте, Grammer, Вы писали:

AppDomain.CurrentDomain.AssemblyResolve ?
A journey of a thousand miles must begin with a single step © Lau Tsu
Re[3]: Загрузка библиотек и путь их поиска...
От: stump http://stump-workshop.blogspot.com/
Дата: 04.04.06 14:48
Оценка: 3 (1)
Здравствуйте, Grammer, Вы писали:

G>Вопрос:

G>Как изменить путь поиска при загрузки dll и её последующем использовании

G>то есть по абсолютному пути я могу загрузить сборку но она ссылается на другую сборку которая лежит в папке плагинов

G>а исполняемая среда ищет почему то только в основной папке приложения...

G>изменение CurrentDirectiory не помогло


Знаю способ. Очень хорошо помогает.
AppDomain.AppendPrivatePath(string path)
не помню точно как надо путь указывать относительно basedirectory или абсолютный.
Понедельник начинается в субботу
Re[5]: Загрузка библиотек и путь их поиска...
От: Аноним  
Дата: 05.04.06 07:20
Оценка:
Здравствуйте, adontz, Вы писали:

A>Здравствуйте, Grammer, Вы писали:


A>AppDomain.CurrentDomain.AssemblyResolve ?


не пойму чем оно мне поможет? объясните плиз если не сложно?
Re[4]: Загрузка библиотек и путь их поиска...
От: Grammer  
Дата: 05.04.06 07:50
Оценка:
S>Знаю способ. Очень хорошо помогает.

очень хорошо помогает?? да это единственный привильный способ!
огромное спасибо

S>AppDomain.AppendPrivatePath(string path)

S>не помню точно как надо путь указывать относительно basedirectory или абсолютный.

да и еще сейчас AppendPrivatePath obsolete и рекуомендуют
AppDomain.CurrentDomain.SetupInformation.PrivateBinPath

где папки задаются через ";"
AppDomain.CurrentDomain.SetupInformation.PrivateBinPath = "PluginDir1;PluginDir2"

не знаю почему не рекомендуют использовать AppendPrivatePath ведь она по сути лишь добавляет в вышеупомянутое проперти путь...
Re[5]: Загрузка библиотек и путь их поиска...
От: Аноним  
Дата: 05.04.06 08:06
Оценка:
Здравствуйте, Grammer, Вы писали:

S>>Знаю способ. Очень хорошо помогает.


G>очень хорошо помогает?? да это единственный привильный способ!

G>огромное спасибо

S>>AppDomain.AppendPrivatePath(string path)

S>>не помню точно как надо путь указывать относительно basedirectory или абсолютный.

G>да и еще сейчас AppendPrivatePath obsolete и рекуомендуют

G>
G>AppDomain.CurrentDomain.SetupInformation.PrivateBinPath
G>

G>где папки задаются через ";"
G>
G>AppDomain.CurrentDomain.SetupInformation.PrivateBinPath = "PluginDir1;PluginDir2"
G>

G>не знаю почему не рекомендуют использовать AppendPrivatePath ведь она по сути лишь добавляет в вышеупомянутое проперти путь...


скажите а зачем плюгины ???

NET приложения и так подгружают когда надо dll

ну если только потом выгружать но слышал что проблемы с этим

или что то поменялось
Re[6]: Загрузка библиотек и путь их поиска...
От: Кодёнок  
Дата: 05.04.06 08:35
Оценка:
Здравствуйте, Аноним, Вы писали:

А>скажите а зачем плюгины ???

А>NET приложения и так подгружают когда надо dll
А>или что то поменялось

Про фильтры фотошопа, плагины для фара, миранды, расширения firefox, тулбары/BHO для IE слышал?
Re[6]: Загрузка библиотек и путь их поиска...
От: adontz Грузия http://adontz.wordpress.com/
Дата: 05.04.06 10:18
Оценка:
Здравствуйте, Аноним, Вы писали:

А>не пойму чем оно мне поможет? объясните плиз если не сложно?


Обработчик этого события вызывается когда не удалось загрузить сборку. Обработчик может загрузить её сам, пользуясь своими методами.
A journey of a thousand miles must begin with a single step © Lau Tsu
Загрузка библиотек и путь их поиска...
От: Аноним  
Дата: 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 здесь
}


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Загрузка библиотек и путь их поиска...
От: Аноним  
Дата: 03.04.06 13:26
Оценка:
В обработчике события OnAssemblyResolveEventHandler в параметре
ResolveEventArgs args находится имя assembly, которое framework не смог загрузить. Вам надо, зная имя этой assembly, загрузить ее в AppDomain.

Смотрите документацию по AppDomain.AssemblyResolve Event в MSDN. Там есть примеры, как это сделать.


данное сообщение получено с www.gotdotnet.ru
ссылка на оригинальное сообщение
Re[2]: Загрузка библиотек и путь их поиска...
От: romstyop  
Дата: 21.01.07 12:16
Оценка:
В> // 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)
Re[5]: Загрузка библиотек и путь их поиска...
От: NoOneKnows  
Дата: 21.01.07 12:49
Оценка:
Здравствуйте, Grammer, Вы писали:

G> ... да это единственный привильный способ!


Отнюдь. Это всего-то возможность конфигурирования приложения в рантайме. Изначально все решается весьма просто: в конфигурационном файле вашего приложения необходимо было добавить элемент <probing>, примерно так:
<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <probing privatePath="bin;bin2\subbin;bin3"/>
      </assemblyBinding>
   </runtime>
</configuration>


privatePath указывает подкаталоги, относительно корневого каталога приложения, в которых CLR может попытаться найти сборки. Разделются подкаталоги точками с запятыми (см. пример).

Если редактировать конифгурационный файл текстовым редактором не по душе — обратите внимание на конфигурационные утилиты (Панель управления -> Администрирование -> Microsoft .NET Framever 5.0 Configuration ( ) ) — выбираете свое приложение, и конфигурите, конфигурите, конфигурите...

G>не знаю почему не рекомендуют использовать AppendPrivatePath ведь она по сути лишь добавляет в вышеупомянутое проперти путь...


Просто предположение. Может, потому, что она не CLS компилант, и, чисто идеологически, ее использовать грешно.
С уважением, Рамиль Сам Ду Нар.
Почти самый отрицательный
Автор: NoOneKnows
Дата: 08.06.06
РСДНовец.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.