Утилитки
05
Сен
6

ILMerge

Как Вы знаете Microsoft Dynamics CRM 2011 (а до этого CRM 4) не поддерживает ссылки на кастомные сборки из сборок плагинов. Вы ограничены сборками .NET Framework и сборками из SDK.

Если Вы хотели сослаться на кастомную сборку, у Вас есть следующие варианты:

  • Зарегистрировать собрку плагина на диске и ссылаться на любые сборки в той же папке;
  • Зарегистрировать кастомную сборку в GAC и ссылаться на нее;
  • Включить исходный кастомный код целиком в сборку плагина.

С введением Решений в CRM 2011 первые два варианта становятся совсем не привлекательными, поскольку требуют дополнительных усилий по переносу кастомизации между средами. Кроме того, первые два варианта не работают для CRM Online, поскольку плагины там регистрируются только в базе. Если же применить последний вариант, то пропадает вся выгода ссылок на сборки.

Но есть инструмент, который поможет Вам решить проблему – ILMerge. Эта утилита выполняет одну простую задачу – сливает несколько .NET сборок в одну. Посмотрим как зарегить это чудо в CRM:

  • Предположим, что у нас есть библиотека PluginLibrary.dll, на которую имеется ссылка из какого-либо плагина. Скомпилируйте проект плагин (в качестве платформы выберите Any CPU), в результате чего, в папке компиляции появятся все участвующие в проекте сборки;
  • Скачайте и установите ILMerge;
  • Прежде, чем мы сможем начать сливание сборок, есть несколько вещей, которые нужно сделать, чтобы заставить ILMerge работать с .NET 4.0. Во-первых, нужно подправить файл ILMerge.exe.config (или создать его):
    <?xml version="1.0" ?>
    <configuration>
    	<startup 
    		useLegacyV2RuntimeActivationPolicy="true">
    		<requiredRuntime 
    			safemode="true" 
    			imageVersion="v4.0.30319" 
    			version="v4.0.30319"
    		/>
    	</startup>
    </configuration>
    

    Если Вы будете запускать ILMerge на 64-битной машине, то Вы должны будете указать расположение сборок 32-битной версии .NET 4.0. Если Вы не сделаете этого, то ILMerge попытается загрузить 64-битные сборки. А так как инструмент собран как 32-битный, то это выдаст ошибку при использовании 64-битных .Net сборок. Обычно эти сборки расположены в C:\Windows\Microsoft.NET\Framework\v4.0.30319.

    С другой стороны ILMerge не сможет скушать 64-битные сборки, в то время как в CRM 2011 можно загрузить только 64-битные, т.к. CRM 2011 имеет только 64-битную версию. Поэтому, чтобы удовлетворить и требованиям CRM и требования ILMerge, плагин и должен быть скомпилирован как нейтральная платформа (Any CPU), т.е. может быть загружен и как 32-битное и как 64-битное решение.

  • После этой предварительной подготовки можно запускать инструмент:
    ilmerge /keyfile:PrivateKey.snk /target:library /copyattrs /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /out:CompletePlugin.dll MyPlugin.dll PluginLibrary.dll
    

    Его параметры таковы:

    • keyfile: задает файл ключа, который используется для подписи итоговой сборки. Все сборки регистрируемые в CRM должны быть подписаны. Таким образом, это необходимый параметр;
    • target: указывает, что итоговый файл должен быть DLL;
    • copyattrs: сливает атрибуты заданные на уровне сборок. Этот атрибут будет Вам полезен, например, если Вы включили в Вашу сборку сгенерированные (CrmSvcUtil.exe) классы объектов, поскольку это гарантирует, что атрибут сборки, ProxyTypesAssemblyAttribute, будет присутствовать в итоговой сборке;
    • targetplatform: версия .NET и путь к сборкам. Если Вы запускаете ILMerge на 32-битной машине, то путь задавать не требуется;
    • out: имя выходного DLL-файла;
    • Список сборок: список сборок, которые будут слиты.

Как только инструмент закончит работу, итоговую сборку можно зарегистрировать в CRM. Учтите только, что слитая сборка не может превышать максимальный размер установленный в CRM 2011.




Автоматизация

Вы можете немножко автоматизировать использование ILMegre. Слияние IL могло быть осуществлено 2 способами:

  • Создать cmd-файл и включить в него вышеприведенный код и когда нужно запускать его;
  • Автоматически запускать слиянии при компиляции проекта. Для этого Вам нужно включить код запуска ILMerge в событие build проекта VS:
    "$(SolutionDir)Library\ILMerge" /t:library /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /copyattrs /keyfile:"$(SolutionDir)Library\mykey.snk" /out:"$(SolutionDir)Plugins\OutputPluginsLibrary\ PluginsLibrary.dll" "$(SolutionDir)Plugins\$(OutDir)Entities.dll" "$(SolutionDir)Plugins\$(OutDir)Plugins.dll"
    

    Здесь используется несколько макросов

    • $(SolutionDir) – папка решения VS;
    • $(OutDir) – путь к папке с выходным файлом, относительно папки проекта.
Комментарии (6)
  • Павел 05.09.2011

    >>Как Вы знаете Microsoft Dynamics CRM 2011 (а до этого CRM 4) не поддерживает ссылки на кастомные сборки из сборок плагинов

    Это не так.
    1. Для всего есть GAC с которым всё прекрассно работает.
    2. Если кастомные сборки поместить в bin каталог вебсайта — синхронные плагины прекрассно будут работать. С асинхронными — другая песня, но на то есть GAC.

  • slivka_83 05.09.2011

    Про GAC тоже написано в статье 🙂 Но этот способ обладает худшей переносимостью чем через Решения, так же как и размещение в папке bin 🙂

  • eXhaustic 05.09.2011

    спасибо, весьма ценный материал

  • Алексей Шачнев 05.09.2011

    Вопрос по близкой теме. Вот написал я плагин, это .dll и рядом с ней файлик .config имеется. Беру Plugin Registrating Tool из SDK, регистрирую плагин в database, а он не работает — не видит своего конфига. Как быть? Спасибо!

  • g.Naukovych 05.09.2011

    1. Попробуйте зарегистрировать dll на файловую систему.
    2. Добавьте Ваши настройки в UnSecure параметры плагина. Чтобы не использовать файл конфига.
    Мы к примеру раньше там хранили строки подключения к БД.

  • Dmitry 05.09.2011

    способ с гаком и тем более фс годиться когда у вас 1 сервер (макс 2)
    а если рассмотреть кластер в котором более 10 серверов — как вы будете обновлять или разворачивать ваше решение.
    БД в данном случае предоставляет центр хранение всех ресурсов и решает эти проблемы за вас

*

code