Способ загрузить DLL из центрального репозитория

У нас есть партия продуктов и существуют некоторые общие DLLs через приложение каждого продукта. Прямо сейчас мы копируем каждый общий DLL в каталог bin каждого продукта и рассматриваем их как приватную сборку. Это излишне увеличивает msi размер каждого продукта и когда проблема происходит в DLL, мы должны создать msi каждого продукта включение DLL и развернуть его.

Должен там так или иначе дать приложению продукта команду использовать общий частный каталог, который будет использоваться для загружаемых DLL [использующий явную схему..]? [Отметьте: Добавление частного каталога для СОЕДИНЕНИЯ КАНАЛОМ ENV не предоставит решение, как будто существует DLL с тем же именем, существуют в каталоге SYSTEM, который взял бы полномочие по нашему частному каталогу]

- Kartlee

9
задан Rubens Farias 28 December 2009 в 14:48
поделиться

5 ответов

Если вы говорите о .NET, вы можете:

  • Загрузить вашу DLL прямо из базы данных с помощью Assembly.Load(byte[])
  • с помощью Assembly. TypeResolve event
  • Используя TypeProvider class
  • Определив каталог зонда в вашем конфигурационном файле

Like:

<configuration>   
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
            <probing privatePath="bin"/>
        </assemblyBinding>
    </runtime>
</configuration>
1
ответ дан 4 December 2019 в 21:10
поделиться

Я не уверен, что это то, что вы ищете, но там, где я сейчас работаю, мы используем общий UNC путь для всех наших DLL.

У нас есть нечто похожее на ...

\\server01\productionLibrary, чтобы в процессе работы читать DLL, каждая из которых находится в своем собственном каталоге.

и

\\server01\developmentLibrary, которая зеркально отражает производственную библиотеку, и это то, что разработчики используют в процессе разработки.

Когда мы объединяем код после завершения тестирования, мы разворачиваем его в производственную библиотеку. Все проекты ссылаются на рабочую библиотеку, когда они встроены в MSI-файлы для развертывания. Наша автоматизированная система собирает проекты в MSI и проверяет, что все DLL указывают на производственную библиотеку, так что нет шансов, что она случайно использует рабочую копию.

Надеюсь, это поможет.

.
0
ответ дан 4 December 2019 в 21:10
поделиться

Я не уверен, что правильно понял вопрос, но если вы находитесь в .Net, то есть кэш глобальной ассамблеи (GAC): http://en.wikipedia.org/wiki/Global_Assembly_Cache

Он кэширует сборки и разрешает их повторное использование приложениями (как в .net framework). Вам просто нужно будет зарегистрировать сборку в GAC во время установки, например, предоставить "установку вашего фреймворка" со всеми общими сборками, и это может быть установлено только один раз.

.
0
ответ дан 4 December 2019 в 21:10
поделиться

Вы не указываете, является ли ваше окружение .NET или прямой Win32.

Я предполагаю, что это Win32, потому что если его .NET, то технологии для этого гораздо ближе в плане таких вещей, как кэш глобальной ассамблеи.

В терминах Win32 можно загружать Dll из общего хранилища одним из двух способов:

  • Использовать LoadLibrary с явными полными путями. Это означает, что вы не можете использовать статическое линкование - все функции dll, используемые во всех продуктах, будут доступны через GetProcAddress. Вы не можете импортировать классы c++ из dll, загруженных через LoadLibrary - они должны быть статически привязаны к работе, так что такой подход может быть или не быть жизнеспособным. Нетрудно записать shim заголовочные файлы, которые маскируются под интерфейс dll и делают своевременную загрузку dll и GetProcAddress по мере необходимости для каждого вызова.

  • Другой вариант - превратить dll в так называемые "боковые сборки" и установить их в хранилище WinSxS. Не бойтесь большого имени. "боковая сборка" означает "файл Dll плюс манифест с информацией о версии". Каждое из различных приложений затем поместит "сильное имя" - которое включает в себя информацию о версии - в свой манифест приложений для каждой используемой им dll, и загрузчик Win32 Dll воспользуется этим, чтобы выбрать правильный экземпляр общей dll из хранилища WinSxS. Основной процесс описан в статье MSDN Guidelines for Creating Side-by-side Assemblies


On Windows versions 6.1 and up (Windows Server 2008 и иронично названная Windows 7). Файлы конфигурации приложений DO NOW поддерживают зондирующий элемент в Файлы конфигурации приложений

Это означает, что Вы должны иметь возможность указать путь (относительно Вашего приложения) к папке, содержащей dll-сборки, которые Вы хотите загрузить.


Я провел некоторое тестирование в Windows 7, и это работает:

Предположим, что у вас установлено приложение app1.exe в \Program Files\App1, которое зависит от некоторых общих dll "thedll.dll"

В папке приложения (\Program Files\App1) создайте файл App1. exe.config и дайте ему следующее содержимое :

<configuration>   
   <windows>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="..\AcmeCommon"/>
    </assemblyBinding>
  </windows>
</configuration>

Теперь создайте папку с именем \Program Files\AcmeCommon, а в ней папку acme.thedll, и скопируйте thedll.dll в \Program Files\AcmeCommon\acme.thedll

Также создайте файл в папке AcmeCommon\acme. adll называется acme.thedll.manifest - это будет манифест сборки, описывающий сборку под названием 'acme.thedll'

Содержимое манифеста acme.thedll.manifest будет:-

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity name="acme.thedll" version="1.2.3.4" processorArchitecture="x86"  type="win32"/>
    <file name="thedll.dll"/>
</assembly>

Теперь у нас есть общая dll, в общем месте, в виде родной sxs сборки. У нас есть приложение с конфигурационным файлом, который на сервере Windows 7 и 2008 (и выше) скажет ему искать сборки в общем месте. Но приложение все еще пытается подключиться к dll в качестве dll, а не через сборку.

Чтобы заставить приложение загрузить сборку, нам нужно добавить файл манифеста в приложение. Если вы используете визуальную студию, то, скорее всего, ваши приложения уже настроены на создание и встраивание манифестов через линкер и настройки проекта манифеста. В этом случае самый простой способ рассказать приложению о сборке - это пересобрать его после добавления следующего кода хотя бы в один заголовочный или c/cpp файл проекта :-

#pragma comment(linker,"/manifestdependency:\"type='win32' name='acme.thedll' version='1.2.3.4' processorArchitecture='x86' language='*'\"")

Если вы используете более старую среду сборки, в которой манифесты создаются вручную, то вам необходимо объединить следующий xml с манифестом app1.exe.manifest в папке App1:

<dependency>
  <dependentassembly>
    <assemblyIdentity type="win32" name="acme.thedll" version="1.2.3.4"   processorArchitecture="x86" language="*"/>
  </dependentassembly>
</dependency>

Это должно замкнуть круг: Когда приложение загрузится, загрузчик win32 загрузит манифест приложения (app1.exe.manifest или встроенный в качестве ресурса RT_MANIFEST) и узнает о сборке "acme.thedll". Он также загрузит файл конфигурации приложения (app1.exe.config) и узнает о закрытом пути поиска сборок. Затем он загрузит и добавит "acme.thedll.manifest" в "контекст активации" приложения. Затем, когда загрузчик попытается загрузить "thedll.dll", он будет искать db контекста активации, найдет его в сборке acme.thedll и загрузит его из места расположения сборок.

.
8
ответ дан 4 December 2019 в 21:10
поделиться

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

Скорее всего, это поможет только в том случае, если вы пишете плагинную систему, где ваши плагины динамически соединены с dll, которые вы хотите хранить в нестандартном каталоге. Если вы знаете все о dll, с которыми они связаны, вы можете явно загрузить эти dll, используя их полный путь до того, как вы загрузите dlls (подключаемые модули), которые зависят от них динамически. Так как dll уже находится в памяти, когда Ваш плагин должен найти ее, он будет использовать версию в памяти. Вы можете выгрузить эксплицитную загрузку, которую Вы сделали перед загрузкой плагина, и Вы можете идти.

К сожалению, это не сработает, если Ваш основной exe должен загрузить dll из произвольных мест, так как Вы не можете войти вперед обычного процесса загрузки dll.

0
ответ дан 4 December 2019 в 21:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: