Проблема с AppDomain.ResourceResolve.

Автор Тема: Проблема с AppDomain.ResourceResolve.  (Прочитано 3869 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Проблема с AppDomain.ResourceResolve.
« : 16-04-2014, 12:05:39 »
Событие AppDomain.AssemblyResolve работает прекрасно (много лет пользуюсь). Недавно решил воспользоваться аналогичным для ресурсов: AppDomain.ResourceResolve. Сборка с найденным ресурсом успешно грузится, как и ожидалось, но затем, при попытке использования подгруженного локализованного ресурса, получаю исключение. На разных форумах создавал тему и выкладывал пример "Hello World" демонстрирующий проблему. Однако всё глухо. Описание проблемы, пример кода, скрин и архив с исходниками примера выложил здесь.

P.S. Прописывать дополнительные каталоги поиска в xml элементе probing файлов acad.exe.config и accoreconsole.exe.config не имеет смысла, т.к. плагины находятся не в каталоге AutoCAD (по вполне понятным причинам).

Оффлайн Josser

  • ADN Club
  • Сообщений: 14
  • Карма: 0
Re: Проблема с AppDomain.ResourceResolve.
« Ответ #1 : 16-04-2014, 20:48:44 »
Вот вариант, который работает.
Я подписался на событие AssemblyResolve, а не ResourceResolve.
В этом случае оно (событие), почему не знаю, происходит дважды. Поэтому отписываюсь от него в обработчике события.
Код - C# [Выбрать]
  1. namespace HelloWorld {
  2.   class Program {
  3.     static void Main(string[] args) {
  4.       AppDomain domain = AppDomain.CurrentDomain;
  5.       Thread thread = Thread.CurrentThread;
  6.       thread.CurrentUICulture = new CultureInfo("en");
  7.       domain.AssemblyResolve += domain_ResourceResolve;
  8.       ResourceManager res = new ResourceManager(typeof(Program));
  9.       Console.WriteLine(res.GetString("Message"));
  10.       Console.WriteLine("Press any key to exit...");
  11.       Console.ReadKey();
  12.       res.ReleaseAllResources();
  13.     }
  14.  
  15.  
  16.     static System.Reflection.Assembly domain_ResourceResolve(object sender, ResolveEventArgs args)
  17.     {
  18.         AppDomain.CurrentDomain.AssemblyResolve -= domain_ResourceResolve;
  19.         Assembly assembly = typeof(Program).Assembly;
  20.         String name = Path.Combine(Path.GetDirectoryName(assembly.Location),
  21.         String.Format("resources\\en\\{0}.resources.dll", Path.GetFileNameWithoutExtension(
  22.         assembly.Location)));
  23.         if (!File.Exists(name))
  24.         {
  25.             Console.WriteLine("'{0}' file not found.", name);
  26.             return null;
  27.         }
  28.         else
  29.         {
  30.             Assembly result = Assembly.LoadFrom(name);
  31.             if (result != null)
  32.                 Console.WriteLine("'{0}' loaded.", name);
  33.             return result;
  34.         }
  35.     }
  36.   }
  37. }
« Последнее редактирование: 17-04-2014, 00:45:58 от Josser »
... пути твои в водах многих, и следы твои не познaются.

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Проблема с AppDomain.ResourceResolve.
« Ответ #2 : 17-04-2014, 11:27:56 »
Да, действительно, если тот же самый код зарегистрировать на событие AssemblyResolve (вместо ResourceResolve), то всё работает почти так, как нужно (если бы не двойная генерация события). Двойная генерация не смертельна (в данном случае), хотя и неприятна... Отписываться от события смысла нет, т.к. если выполнить это, то позднее не удастся найти все прочие файлы ресурсов.

Спасибо.

P.S. Хотелось бы конечно понять, почему должным образом не срабатывает вариант с подпиской на ResourceManager и почему AssemblyResolve срабатывает дважды, но это уже второстепенные вопросы, ответы на которые вряд ли будут получены (нет времени возиться с этим).
« Последнее редактирование: 17-04-2014, 11:44:01 от Андрей Бушман »

Оффлайн Андрей БушманАвтор темы

  • ADN Club
  • *****
  • Сообщений: 2000
  • Карма: 163
  • Пишу программки...
    • Блог
  • Skype: Compositum78
Re: Проблема с AppDomain.ResourceResolve.
« Ответ #3 : 17-04-2014, 12:26:53 »
Кстати, если при "ручном управлении" (т.е. в коде метода domain_ResourceResolve) попытаться в качестве ресурса загрузить файл иной локализации, то происходит всё то же исключение. Т.е. если текущая культура "en", а загрузить пытаюсь файл  .\resources\ru\HelloWorld.resources.dll, то всё завершится крахом. Но если грузить .\resources\en\HelloWorld.resources.dll, то всё работает как нужно. Странно... Уж если событие предназначено для перехода на "ручное управление", то нет смысла прятать штурвал под стеклянным колпаком...