Сообщество программистов Autodesk в СНГ

ADN Club => AutoCAD .NET API => Тема начата: MikhailTAP от 30-06-2015, 07:41:44

Название: Несколько плагинов с общими библиотеками
Отправлено: MikhailTAP от 30-06-2015, 07:41:44
Добрый день!
В нашей компании есть следующая проблема: имеется несколько плагинов использующих общие библиотеки. При этом, если на машине установлен один из плагинов, и рядом ставится второй плагин с обновлённой общей библиотекой, то возникает конфликт. Любой из установленных плагинов может не находить нужных методов (если сигнатура метода была изменена), или же использовать методы из старой библиотеки.
Каким образом можно решить эту проблему?
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Пекшев aka Modis от 30-06-2015, 09:46:52
Что-то я не понял - если рядом ставится второй плагин с обновленной общей библиотекой, то как тогда могут быть использованы методы из старой библиотеки? Разве они не заменены на новые?
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 30-06-2015, 10:32:12
Если вы изменяете логику работы метода - то меняйте и имя. В конце-концов, можно просто добавлять циферки на конце (SuperPuperMethod, SuperPuperMethod1...). А если добавляете новый метод с другой сигнатурой, то конфликтов по идее быть не должно (в NET).
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Андрей Бушман от 30-06-2015, 11:09:37
Каким образом можно решить эту проблему?
Взаимодействовать посредством интерфейсов. Принцип аналогичен тому, который в COM.

.NET гораздо более гибок, чем COM. Например, ты можешь править уже имеющиеся старые интерфейсы, добавляя новые методы и всё при этом будет работать. Главное при этом - не трогать уже имеющиеся старые, иначе получишь то, что ты получил. Тогда конфликтов быть не должно, насколько мне известно. По факту, в твоём случае, ноги растут от плохого проектирования. Прежде чем садиться писать код, неплохо было бы для начала (помимо анализа проблемы) выполнить проектирование и лишь затем садиться за реализацию. В процессе проектирования в т.ч. заранее продумываются и программные интерфейсы с учётом дальнейших возможных изменений.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 30-06-2015, 11:38:13
В нашей компании есть следующая проблема: имеется несколько плагинов использующих общие библиотеки. При этом, если на машине установлен один из плагинов, и рядом ставится второй плагин с обновлённой общей библиотекой, то возникает конфликт.
Решение очевидно - не делать так. Или не менять общие библиотеки или обновлять и ставить одновременно все плагины, использующие эти общие библиотеки.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Андрей Бушман от 30-06-2015, 11:40:39
Решение очевидно
очевидно в текущем контексте. - так будет корректней.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Андрей Бушман от 30-06-2015, 11:53:15
Возможно будет интересно...

Если говорить о варианте, когда сохраняются разные версии DLL (то ли под разные версии CAD, то ли под разные версии .NET, то ли оба варианта вместе)... Разные версии AutoCAD используют разные версии .NET Framework. Т.о. в одном каталоге разместить одноимённые DLL, собранные под разные версии .NET не получится. Варианта два:
За всю свою историю работы я ни разу не столкнулся с проблемами в работе своих .NET плагинов, использующих мною же созданных  (и, по мере необходимости, обновляемых) общих DLL. Это обусловлено в первую очередь тем, что очередная версия DLL не изменяет состав и сигнатуры уже существующих методов. Я могу добавлять новые или изменять реализацию, но не меняю "старые контракты". Взаимодействие выполняю, как правило, посредством интерфейсов.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 30-06-2015, 11:58:09
За всю свою историю работы я ни разу не столкнулся с проблемами в работе своих .NET плагинов, использующих мною же созданных общих DLL.
Тут существенно местоимение "Я". Замени его на "Мы" и вполне возможно что возникнет проблема.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Андрей Бушман от 30-06-2015, 12:00:52
и вполне возможно что возникнет проблема.
И на чём же она должна возникнуть, если контракт не нарушен? Пример, если не сложно.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 30-06-2015, 13:13:26
И на чём же она должна возникнуть, если контракт не нарушен? Пример, если не сложно.
Главная проблема именно в том, что если созданием/развитием общих библиотек занимается не один, а несколько человек, то контракты часто нарушаются ("правила игры меняются по ходу игры"). Результаты мы видим у MikhailTAP.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: MikhailTAP от 01-07-2015, 07:19:06
В качестве эксперимента сделал следующие: загружаю плагин1 (использует более раннюю версию общей библиотеки), затем загружаю плагин2(использует обновлённую версию общей библиотеки). Потом в VS посмотрел загруженные модули, и получается, что в такой ситуации, общая библиотека подгружаемая плагином2 - игнорируется (в памяти висит только библиотека плагина1).
Вариантом был бы StrongName, но сделать это невозможно, т.к. библиотеки Акада которые используются - не подписаны.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Андрей Бушман от 01-07-2015, 08:05:00
Вариантом был бы StrongName, но сделать это невозможно, т.к. библиотеки Акада которые используются - не подписаны.
давно известный факт, причём автодеск утверждает, что это безобразие создано специально (http://adndevblog.typepad.com/autocad/2012/07/can-i-sign-my-autocad-net-plug-in-with-a-strong-name.html).
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Андрей Бушман от 01-07-2015, 08:24:17
Только сейчас заметил, что на мой вопрос в комментах по обозначенной выше ссылке ответили. Что же, на первый взгляд аргументация выглядит достаточно разумной.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 27-01-2017, 20:56:23
Эх, поднимем такую хорошую тему :)
Тоже столкнулся с проблемой общих сборок.
Ситуация такая: есть несколько приложений, которые используют несколько общих вспомогательных DLL. Одна библиотека расширяет функционал AutoCAD API, вторая - Civil 3D API, третья - вспомогательная библиотека с механизмом реализации ссылок между объектами чертежа, ну и т.д. Каждое приложение имеет свой собственный инсталлятор и устанавливается отдельно в свою папку Bundle. Соответственно, каждое из приложений тянет в свою папку эти вспомогательные DLL. Упрощенная схема на рисунке Current. Так вот, если я внес какие-то изменения во вспомогательные DLL, пересобрал приложения, создал новые инсталляторы и отправил пользователям, но они по какой-то причине не обновили все приложения, то возникают вполне логичные различные неполадки несовместимости при их загрузке в AutoCAD. Со стороны пользователя, это, конечно же, значительное неудобство. Получается, я облегчаю себе жизнь, как разработчику, вынося повторяющийся функционал в общие библиотеки, но этим усложняю жизнь пользователям. Думаю, что это не очень хорошо.
Как выход из этой ситуации, мне видится создание отдельной инсталляции для вспомогательных библиотек. Можно это сделать в виде отдельного компонента и внедрять как необходимый компонент в инсталлятор каждого приложения. При установке, будет проверяться версия установленного пакета библиотек и, при необходимости, обновляться. Схема не нова, нечто похожее используют многие инсталляторы приложений Windows. Взять, хотя бы, для примера, установку нужной версии .NET Framework при установке AutoCAD.
Разумеется, помещать пакет библиотек логично в таком варианте в отдельном Bundle. Упрощенная схема на рисунке Project. На первый взгляд, вроде работоспособно. Каких-то проблем с технической реализацией этой схемы я пока не вижу. Но нужно как-то обеспечить загрузку вспомогательных библиотек раньше загрузки всех приложений, которые их используют. Иначе AutoCAD их сам не найдет и не загрузит, когда DLL приложения запросит какой-нибудь объект из вспомогательной DLL, и загрузка приложения прервется ошибкой. Как я понимаю, загрузка Bundle выполняется в AutoCAD по алфавитному порядку названий папок Bundle в каталоге ApplicationPlugins. Получается, что нужно обеспечить папке Bundle с библиотечными DLL такое название, чтобы она была "выше всех". На мой взгляд, это довольно "топорный" способ т.к. нет гарантии, что AutoCAD и дальше будет так загружать пакеты. С его точки зрения все Bundle равнозначны и независимы. Да и хотелось бы давать свободные названия для папок Bundle, а не что-то типа "0Library.bundle", "1Application1.bundle", "2Application2.bundle". Но, пока, ничего лучше придумать не могу. Может быть, есть у кого-то интересные идеи по данному вопросу? Или критические замечания по такой схеме?
Спасибо.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 27-01-2017, 22:08:02
Может быть, есть у кого-то интересные идеи по данному вопросу? Или критические замечания по такой схеме?
Пока на уровне интуиции я могу сказать, что так делать не следует.
Во-первых не следует полагаться на порядок загрузки. Я не проверял, но мне кажется, что он читает каталоги внутри ApplicationPlugins и обрабатывает их не в алфавитном порядке, а в том порядке в котором они находятся в каталоге (а это совершенно необязательно отсортированные по алфавиту).
Во-вторых, я бы предпочел в методе Initialize своих приложений загружать необходимые сборки если они еще не загружены, а если их загрузить не удаётся, то сообщал бы пользователю.
В-третьих, я бы вообще не включал их ни в какие BUNDLE'ы - если это библиотечные файлы, то зачем отдавать их загрузку на волю AutoCAD?
IMHO.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 28-01-2017, 00:42:44
Во-первых не следует полагаться на порядок загрузки. Я не проверял, но мне кажется, что он читает каталоги внутри ApplicationPlugins и обрабатывает их не в алфавитном порядке, а в том порядке в котором они находятся в каталоге (а это совершенно необязательно отсортированные по алфавиту).
Вот да, именно так! На уровне подсознания где-то, есть понимание, что это весьма ненадежно :)
Во-вторых, я бы предпочел в методе Initialize своих приложений загружать необходимые сборки если они еще не загружены, а если их загрузить не удаётся, то сообщал бы пользователю.
А это уже весьма интересная идея! Надо будет проверить, как это будет работать.
В-третьих, я бы вообще не включал их ни в какие BUNDLE'ы - если это библиотечные файлы, то зачем отдавать их загрузку на волю AutoCAD?
Да, согласен. Если Ваша идея с подгрузкой из Initialize хорошо покажет себя в работе, то от загрузки библиотеки через bundle можно отказаться.
Попробую сделать небольшой тестовый проект и обкатать идею.
Спасибо!
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 28-01-2017, 03:05:42
А это уже весьма интересная идея! Надо будет проверить, как это будет работать.
Главное, чтобы у тебя не было статических переменных, которые инициализируются значениями, использующие классы и методы из этих "библиотек". Насколько я помню инициализация статических переменных происходит до вызова метода Initialize (могу ошибаться).
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дима_ от 28-01-2017, 08:46:19
Я в этом моменте плюю на размер в угоду надежности. В БД если обновляется любой компонент, то автоматом создается архив со всеми сборками и пр. компонентами и при загрузке автокада "загрузчик" увидев новую версию в БД все переписывает на локальном компе (с учетом "уровня" пользователя) - то есть чистит все "свои" сборки и разворачивает по новой весь загруженный архив. И если что, можно в момент откатить до любой предыдущей версии - пока правда такое "счастье" миновало, но все возможно.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 28-01-2017, 14:08:30
Главное, чтобы у тебя не было статических переменных, которые инициализируются значениями, использующие классы и методы из этих "библиотек". Насколько я помню инициализация статических переменных происходит до вызова метода Initialize (могу ошибаться).
Нет, не ошибаетесь. Это естественное поведение при загрузке любого .NET класса.
Как показали опыты, в самом Initialize, после кода подгрузки вспомогательных DLL, также нельзя использовать методы из этих DLL. Если раскомментить строки 44-46 (обращения к методам вспомогательных библиотек), то метод Initialize не выполнится и DLL с этим кодом не будет загружена. Не знаю, почему так. Возможно, что это тоже естественное поведение .NET, но я с таким еще не сталкивался.
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Runtime;
  4. using System;
  5. using System.IO;
  6. using System.Reflection;
  7.  
  8. namespace Application1
  9. {
  10.     public class AppInitClass : IExtensionApplication
  11.     {
  12.         static bool AssemblyLoad(string path)
  13.         {
  14.             try
  15.             {
  16.                 Assembly.LoadFrom(path);
  17.                 return true;              
  18.             }
  19.             catch (System.Exception ex)
  20.             {                
  21.                 Application.ShowAlertDialog($"Exception: {ex.Message}");
  22.                 return false;
  23.             }            
  24.         }
  25.  
  26.         public void Initialize()
  27.         {
  28.             string appsDirPath = Path.Combine
  29.                 (Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
  30.                 "Autodesk", "ApplicationPlugins", "AppLibrary");
  31.  
  32.             string myLib1Path = Path.Combine(appsDirPath, "MyLibrary1.dll");
  33.             string myLib2Path = Path.Combine(appsDirPath, "MyLibrary2.dll");
  34.             string myLib3Path = Path.Combine(appsDirPath, "MyLibrary3.dll");
  35.  
  36.  
  37.             if (!AssemblyLoad(myLib1Path)
  38.                 || !AssemblyLoad(myLib2Path)
  39.                 || !AssemblyLoad(myLib3Path))
  40.             {
  41.                 return;
  42.             }
  43.  
  44.             //Document adoc = MyLibrary1.Support1.GetActiveDocument(Application.DocumentManager);
  45.             //string appName = MyLibrary2.Support2.GetAppName(Assembly.GetExecutingAssembly());
  46.             //string adocName = MyLibrary3.Support3.GetAdocName(adoc);
  47.  
  48.             Application.ShowAlertDialog("Application #1 loaded!");            
  49.         }
  50.  
  51.         public void Terminate()
  52.         {
  53.  
  54.         }
  55.  
  56.         [CommandMethod("App1Test")]
  57.         public void Run()
  58.         {
  59.             Document adoc = MyLibrary1.Support1.GetActiveDocument(Application.DocumentManager);
  60.             string appName = MyLibrary2.Support2.GetAppName(Assembly.GetExecutingAssembly());
  61.             string adocName = MyLibrary3.Support3.GetAdocName(adoc);
  62.  
  63.             Application.ShowAlertDialog("Application #1 test cmd: OK");
  64.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  65.             ed.WriteMessage("\nApplication #1 test cmd: OK");
  66.         }
  67.     }
  68. }
  69.  
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 28-01-2017, 14:14:25
Я в этом моменте плюю на размер в угоду надежности. В БД если обновляется любой компонент, то автоматом создается архив со всеми сборками и пр. компонентами и при загрузке автокада "загрузчик" увидев новую версию в БД все переписывает на локальном компе (с учетом "уровня" пользователя) - то есть чистит все "свои" сборки и разворачивает по новой весь загруженный архив. И если что, можно в момент откатить до любой предыдущей версии - пока правда такое "счастье" миновало, но все возможно.
У меня "загрузчиков" никаких нет. Для приложений я создаю инсталляторы с помощью WIX. Наверное, в проект инсталляции тоже можно добавить программу, которая будет анализировать уже имеющиеся приложения и библиотеки в них, но я пока до этого не дорос.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 28-01-2017, 14:15:48
Если раскомментить строки 44-46 (обращения к методам вспомогательных библиотек), то метод Initialize не выполнится и DLL с этим кодом не будет загружена. Не знаю, почему так.
Ну для начала их тоже нужно обернуть в try/catch, так как если в Initialize остаётся необработанное исключение, то сборка не работает.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 28-01-2017, 14:22:33
Да нет, исключений там не происходит. Да я, на самом деле, уже что только не делал  :) И по отдельности пробовал раскомментить, и обработку ошибок, и логику методов вспомогательных менял. Ничего не помогает.
Я подозреваю, что есть какой-то механизм проверки обращений метода Initialize к сторонним DLL, и если они в момент обращения к методу недоступны, то сам метод не выполняется. Потому что при дебаге даже не срабатывает точка останова на входе в метод, если хотя бы одна из этих строк не закомментирована.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 28-01-2017, 22:44:36
Главное, чтобы у тебя не было статических переменных, которые инициализируются значениями, использующие классы и методы из этих "библиотек".
Ваш совет натолкнул меня на идею - вынести загрузку библиотек в статический конструктор класса. В таком варианте работает как надо! Еще раз, спасибо за идею! Теперь надо обкатать ее на рабочих сборках.
Итоговый код автозагружаемого класса
Код - C# [Выбрать]
  1. using Autodesk.AutoCAD.ApplicationServices;
  2. using Autodesk.AutoCAD.EditorInput;
  3. using Autodesk.AutoCAD.Runtime;
  4. using System;
  5. using System.IO;
  6. using System.Reflection;
  7.  
  8. namespace Application1
  9. {
  10.     public class AppInitClass : IExtensionApplication
  11.     {
  12.         /// <summary>
  13.         /// Статический конструктор класса
  14.         /// </summary>
  15.         static AppInitClass()
  16.         {
  17.             // составляем путь к папке с библиотечными DLL
  18.             // в данном случае %ProgramData%\Autodesk\ApplicationPlugins\AppLibrary
  19.             string appsDirPath = Path.Combine
  20.                 (Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
  21.                 "Autodesk", "ApplicationPlugins", "AppLibrary");            
  22.  
  23.             // грузим библиотечные DLL
  24.             AssemblyLoad(Path.Combine(appsDirPath, "MyLibrary1.dll"));
  25.             AssemblyLoad(Path.Combine(appsDirPath, "MyLibrary2.dll"));
  26.             AssemblyLoad(Path.Combine(appsDirPath, "MyLibrary3.dll"));
  27.         }
  28.  
  29.         /// <summary>
  30.         /// Безопасный метод загрузки DLL
  31.         /// </summary>
  32.         /// <param name="path">Путь к DLL</param>
  33.         /// <returns>true - загружена, false - не загружена</returns>
  34.         static bool AssemblyLoad(string path)
  35.         {
  36.             try
  37.             {
  38.                 Assembly.LoadFrom(path);
  39.                 return true;
  40.             }
  41.             catch (System.Exception ex)
  42.             {
  43.                 Application.ShowAlertDialog($"Exception: {ex.Message}");
  44.                 return false;
  45.             }
  46.         }
  47.  
  48.         /// <summary>
  49.         /// Метод, выполняемый AutoCAD при загрузке сборки
  50.         /// </summary>
  51.         public void Initialize()
  52.         {
  53.             // Вызываем методы из библиотечных DLL, по одному из каждой
  54.             Document adoc = MyLibrary1.Support1.GetActiveDocument(Application.DocumentManager);
  55.             string appName = MyLibrary2.Support2.GetAppName
  56.                 (Assembly.GetExecutingAssembly()) ?? "*no_app_name*";
  57.             string adocName = MyLibrary3.Support3.GetAdocName(adoc) ?? "*no_adoc_name*";
  58.  
  59.             // Выводим сообщение
  60.             Application.ShowAlertDialog($"{appName} loaded into {adocName}!");
  61.         }        
  62.  
  63.         public void Terminate()
  64.         {
  65.  
  66.         }
  67.  
  68.         /// <summary>
  69.         /// Командный метод для проверки загруженности сборки
  70.         /// </summary>
  71.         [CommandMethod("App1Test")]
  72.         public void Run()
  73.         {
  74.             Document adoc = MyLibrary1.Support1.GetActiveDocument(Application.DocumentManager);
  75.             string appName = MyLibrary2.Support2.GetAppName
  76.                 (Assembly.GetExecutingAssembly()) ?? "*no_app_name*";
  77.             string adocName = MyLibrary3.Support3.GetAdocName(adoc) ?? "*no_adoc_name*";
  78.  
  79.             Application.ShowAlertDialog($"{appName} test command in {adocName}: OK");
  80.             Editor ed = adoc?.Editor;
  81.             ed?.WriteMessage("\n{0} test command in {1}: OK", appName, adocName);
  82.         }
  83.     }
  84. }

Тестовый проект - в архиве (VS 2015)
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Вильдар от 11-02-2020, 12:46:31
Со сторонними библиотеками есть проблемы - использования разных версий в разных плагинах.
Есть предположение, что лучший способ - строгие имена и регистрация в гаке!
Правда, пока на практике не проверял  ::)
И есть много библиотек без строгих имен.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 11-02-2020, 13:09:47
Со сторонними библиотеками есть проблемы - использования разных версий в разных плагинах.
Я уже третий год использую схему, которую описал в предыдущем своём сообщении в этой теме - такой проблемы у меня больше нет.
Нужно придерживаться нескольких правил. Например - ничего не удалять из библиотечной DLL. Можно менять внутренности, но все публичные члены должны быть неизменными. Если что-то перестаёт быть актуальным - помечаю как Obsolete. Библиотечные dll собираю в отдельные MergeModule и добавляю в проект установки каждого плагина. При установке плагина, все вспомогательные DLL, которые он использует, обновляются до новых версий. Но так как из них ничего старого не удаляется, то и старые плагины спокойно используют обновлённые DLL.
Проблема помещения вспомогательных DLL для AutoCAD в GAC была описана ещё Бушманом Андреем, где-то тут есть на форуме, если поискатьобнаружил, что обсуждение этого вопроса - как раз в этой теме ранее было :). Если я правильно помню, суть в том, что DLL из AutoCAD API не подписаны и если в библиотечной DLL есть ссылка на них, то в GAC они не могут быть помещены. Теоретически, конечно, есть вариант писать библиотеки без привязки к AutoCAD API, но, по мне, затрат будет больше, чем выгоды.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Роман Малютин от 08-11-2020, 19:24:33
Ещё раз подниму эту прекрасную тему про совместимость  :)

SQLite - суперпопулярная технология хранения данных.
Плагин#1 использует System.Data.SQLite.dll v.1.0.97, загружается первым, разработан третьей стороной.
Плагин#2 использует System.Data.SQLite.dll v.1.0.112, загружается вторым, мой
Результат - AutoCAD падает с фатальной ошибкой.
Если скопировать более свежую System.Data.SQLite.dll из Плагина#2 в Плагин#1 - всё работает.

Пробовал грузить dll как писал Дмитрий Загорулькин, чтобы получить информацию об ошибке - не вышло.
Подскажите хотя бы направление поиска проблемы. Сигнатуры там не менялись, обычный IDbConnection ...
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 08-11-2020, 19:51:58
Если скопировать более свежую System.Data.SQLite.dll из Плагина#2 в Плагин#1 - всё работает.
Собственно говоря это единственный мне известный метод. Две разных версии одной сборки загрузить в один домен нельзя.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Вильдар от 08-11-2020, 21:38:16
Можно переименовать дллку и грузить ее принудительно. В некоторых случаях помогает.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 08-11-2020, 21:46:56
Вильдар,
Судя по тому, что написано здесь: https://system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki там используются не только managed, но и native dll-файлы. Так что в этом случае точно ничего не получится. Разве что скачать исходники, поменять везде имена и перекомпилировать.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Вильдар от 08-11-2020, 21:51:46
там используются не только managed, но и native dll-файлы
ох, с таким еще не сталкивались, слава богу 😁
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Роман Малютин от 09-11-2020, 00:03:01
Собственно говоря это единственный мне известный метод. Две разных версии одной сборки загрузить в один домен нельзя.
Спасибо. Ох, это прям фиаско.
Может мой вопрос покажется дилетантским и риторическим, но вот интересно, как в компании Autodesk предполагали работу их системы? В плагинах же повсеместно используются популярные библиотеки для типовых операций - работа с БД, экспорт данных в Excel/Word/PDF, всякие там ORM, мапперы... Получается, что конфликт просто неизбежен?
Только в App Store более 4000 приложений, думаю там немало на .net.
Заставлять пользователя рыться в файлах плагинов и выискивать конфликтные библиотеки - это конечно рабочее решение, но в 99% случаев сами знаете что будет.

Можно переименовать дллку и грузить ее принудительно. В некоторых случаях помогает.
Просто сменить имя файла? Проверял, не сработало.

В своем проекте выставил для System.Data.SQLite.dll свойство 'Specific version'=false. Надеюсь, это хоть немного увеличит шансы пользователей в нелегком деле копирования файлов  :)
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Александр Ривилис от 09-11-2020, 00:10:43
Может мой вопрос покажется дилетантским и риторическим, но вот интересно, как в компании Autodesk предполагали работу их системы?
1. Причем здесь AutoCAD? Это касается любого exe-файла, для которого создаётся система плагинов. Тут скорее претензия к Microsoft, что они не предусмотрели такое...
2. Кто заставляет тебя пользоваться сторонними библиотеками в своих приложениях? Для ObjectARX допустима вообще только конкретная версия Visual Studio с конкретным пакетом обновлений. И ничего - никто не жалуется. :-)
В своем проекте выставил для System.Data.SQLite.dll свойство 'Specific version'=false. Надеюсь, это хоть немного увеличит шансы пользователей в нелегком деле копирования файлов 
Теоретически это могло бы помочь если бы под капотом не использовались native dll-файлы. А так очень сомнительно...
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 09-11-2020, 13:28:44
Получается, что конфликт просто неизбежен?
Да, это так. Даже если сделать систему распространения своих приложений таким образом, чтобы исключались конфликты версий вспомогательных библиотек, это не поможет, если используются сторонние плагины с теми же библиотеками других версий. Я, например, тоже System.Data.SQLite использую в одном из плагинов. И я не помню, когда последний раз его версию обновлял.
Возможно, в случае с SQLite можно как-то избежать проблемы, если найти возможность использовать те же самые DLL, которые использует сам AutoCAD для работы с ней. Где-то среди его файлов установки я находил библиотеки SQLite. Но, возможно, что это только в Civil 3D. И, скорее всего, там используется Native версия SQLite.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: avc от 09-11-2020, 18:35:46
Получается, я облегчаю себе жизнь, как разработчику, вынося повторяющийся функционал в общие библиотеки, но этим усложняю жизнь пользователям.
Вот именно. И это одна из причин, почему я пошел обратным путем - один плагин = одна dll. Ни каких вспомогательных. А исходные коды во всех проектах плагинов на 90% одни те же - вставлены в проект как ссылки. Да, я теряю в скорости компиляции, вынужден заталкивать все новые файлы CS во все проекты. Зато у пользователя нет проблем совместимости.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 09-11-2020, 21:59:47
avc, адаптеры к БД тоже свои пишете?  :)
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: avc от 09-11-2020, 22:18:37
Неее :) Доступ к SQL встроен в .Net - им и пользуюсь. А если что-то надо подключить - вариант только искать open source. Пока все что надо находил :)
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Роман Малютин от 09-11-2020, 23:27:14
1. Причем здесь AutoCAD? Это касается любого exe-файла, для которого создаётся система плагинов. Тут скорее претензия к Microsoft, что они не предусмотрели такое...
Претензия не к функционалу. Просто факт не очевидный. На месте человека, который выбирает язык программирования под AutoCAD, я бы хотел это узнать как можно раньше.

Из-за меня тут люди пострадали. Делали-делали свой шедевр, а в итоге пользователь просто удалил их плагин, т.к. он конфликтует с моим. А могло быть и наоборот! :-\

Попытался проскочить нахаляву:
Код - INI [Выбрать]
  1. ildasm /all /out=System.Data.SQLite.il System.Data.SQLite.dll
  2. (правка il файла в VS Code)
  3. ilasm /dll /out=System.Data.SQLite222.dll System.Data.SQLite222.il
Не вышло. Переименовать получилось, работает, но всё равно конфликтует. Теперь застрял на PublicKeyToken. Видимо все же придется компилировать из исходников...
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 11-11-2020, 13:15:47
Сигнатуры там не менялись, обычный IDbConnection ...
Может попробовать через рефлексию? Если вызовов не сильно много, может и не сильно сложно получится.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Роман Малютин от 11-11-2020, 22:36:47
Итак, вот чем закончилась моя история с SQLite:
Поковырял исходники - не моя лига  :) Там такой навороченный MSBuild, что Visual Studio даже файлы классов внутри проекта отобразить не может. Всё подключается на каком-то лютом автомате.

Плюнул я на это дело, и обратился к фрилансерам. $40 - цена вопроса на Upwork. Курс доллара конечно огорчает, зато теперь у меня есть "своя" dll для SQLite, которая ни с кем не конфликтует.
Исходники не понадобились, исправили готовую dll. Сравнил il-код до и после - много мелких изменений, мне не понятных. Похоже софтинка какая-то есть специальная.
Всем спасибо за поддержку.
Название: Re: Несколько плагинов с общими библиотеками
Отправлено: Дмитрий Загорулькин от 12-11-2020, 13:48:35
Тоже вариант  :)