Лучшие практики ILMerge

Используете ли вы ILMerge? Используете ли вы ILMerge для объединения нескольких сборок для упрощения развертывания dll? Были ли у вас проблемы с развертыванием/версией в производстве после сборки ILMerging?

Я ищу несколько советов относительно использования ILMerge для уменьшения трения при развертывании, если это возможно.

Ответ 1

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

Вы не можете выполнить ILMerge любые сборки С++ с собственным кодом. Вы также не можете ILMerge любых сборок, содержащих XAML для WPF (по крайней мере, я не имел успеха с этим). Он жалуется во время выполнения, что ресурсы не могут быть расположены.

Я написал исполняемый файл обертки для ILMerge, где я передаю имя запуска exe для проекта, который я хочу объединить, и имя exe вывода, а затем он отображает зависимые сборки и вызывает ILMerge с соответствующими параметрами командной строки. Теперь гораздо проще, когда я добавляю новые сборки в проект, мне не нужно забывать обновлять сборку script.

Ответ 2

Введение

В этом сообщении показано, как заменить все .exe + .dll files на один combined .exe. Он также сохраняет отладочный файл .pdb неповрежденным.

Для консольных приложений

Вот базовый Post Build String для Visual Studio 2010 SP1, используя .NET 4.0. Я создаю консоль .exe со всеми включенными в нее суб-DLL файлами.

"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards

Основные подсказки

  • Вывод представляет собой файл "AssemblyName.all.exe", который объединяет все под-dll в один .exe.
  • Обратите внимание на каталог ILMerge\. Вам нужно либо скопировать утилиту ILMerge в ваш каталог решений (чтобы вы могли распространять источник, не беспокоясь о регистрации установки ILMerge), либо изменить этот путь, чтобы указать, где находится ILMerge.exe.

Дополнительные подсказки

Если у вас возникли проблемы с работой, включите Output и выберите Show output from: Build. Проверьте правильную команду Visual Studio и проверьте наличие ошибок.

Пример сборки Script

Этот script заменяет все .exe + .dll files на один combined .exe. Он также сохраняет файл .pdb отладки неповрежденным.

Чтобы использовать, вставьте это в свой Post Build шаг под вкладкой Build Events в проекте С# и убедитесь, что вы отредактировали путь в первой строке, чтобы указать на ILMerge.exe:

rem Create a single .exe that combines the root .exe and all subassemblies.
"$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
rem Remove all subassemblies.
del *.dll
rem Remove all .pdb files (except the new, combined pdb we just created).
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp"
del *.pdb
ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb"
rem Delete the original, non-combined .exe.
del "$(TargetDir)$(TargetName).exe"
rem Rename the combined .exe and .pdb to the original project name we started with.
ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
exit 0

Ответ 3

Мы используем ILMerge для блоков приложений Microsoft - вместо 12 отдельных DLL файлов у нас есть один файл, который мы можем загрузить в наши клиентские области, а также структура файловой системы намного опрятно.

После слияния файлов мне пришлось отредактировать список проектов визуальной студии, удалить 12 отдельных assmeblies и добавить один файл в качестве ссылки, иначе он будет жаловаться, что он не сможет найти конкретную сборку. Я не слишком уверен, как это будет работать при пост-развертывании, хотя, возможно, стоит попробовать.

Ответ 4

Я знаю, что это старый вопрос, но мы не только используем ILMerge для сокращения числа зависимостей, но и для интернализации "внутренних" зависимостей (например, automapper, restsharp и т.д.), которые используются утилитой. Это означает, что они полностью абстрагируются, а проект с использованием объединенной утилиты не нужно знать о них. Это снова уменьшает требуемые ссылки в проекте и позволяет при необходимости использовать/обновлять собственную версию той же внешней библиотеки.

Ответ 5

Мы используем ILMerge для нескольких проектов. "Программное обеспечение веб-сервисов" Factory, например, выводит в качестве вывода как 8 сборок. Мы объединим все эти библиотеки DLL в одну DLL, чтобы хост службы должен был ссылаться только на одну DLL.

Это облегчает жизнь, но это тоже не очень важно.

Ответ 6

У нас была та же проблема с объединением зависимостей WPF... ILMerge, похоже, не справляется с ними. Costura.Fody работал отлично для нас, однако, и потребовалось около 5 минут, чтобы пройти... очень хороший опыт.

Просто установите с помощью Nuget (выбрав правильный проект по умолчанию в консоли диспетчера пакетов). Он вводит себя в целевой проект, и настройки по умолчанию немедленно сработали для нас.

Он объединяет все DLL, отмеченные "Копировать локальные" = true, и создает объединенный .EXE(наряду со стандартным выходом), который красиво сжат по размеру (намного меньше, чем общий размер вывода).

Лицензия - это MIT, так что вы можете изменять/распространять по мере необходимости.

https://github.com/Fody/Costura/

Ответ 7

Мы столкнулись с проблемами при объединении DLL, у которых есть ресурсы в одном и том же пространстве имен. В процессе объединения одно из пространств имен ресурсов было переименовано и, следовательно, ресурсы не могли быть расположены. Может быть, мы просто делаем что-то не так, все еще исследуя проблему.

Ответ 8

Обратите внимание, что для окон GUI-программ (например, WinForms) вы захотите использовать переключатель /target: winexe.
Переключатель /target: exe создает объединенное консольное приложение.

Ответ 9

Мы только начали использовать ILMerge в наших решениях, которые перераспределяются и используются в наших других проектах и ​​пока настолько хороши. Кажется, все работает нормально. Мы даже запутали упакованную сборку напрямую.

Мы планируем сделать то же самое с сборками MS Enterprise Library.

Единственная реальная проблема, с которой я вижу, - это управление версиями отдельных сборок из пакета.

Ответ 10

Недавно у меня возникла проблема, когда я собрал сборку в сборке. У меня были некоторые классы, которые они вызывали через отражение в CMS с открытым исходным кодом Umbraco.

Информация для совершения вызова через отражение была взята из таблицы db, у которой было имя сборки и пространство имен класса, который реализован и интерфейс. Проблема заключалась в том, что вызов отражения завершился неудачно, если DLL будет объединена, однако, если dll будет отдельным, все будет работать нормально. Я думаю, что проблема может быть похожа на то, что имеет один longeasy?

Ответ 11

Я только начинаю использовать ILMerge как часть моей сборки CI, чтобы объединить множество мелкозернистых контрактов WCF в одну библиотеку. Он работает очень хорошо, однако новая объединенная библиотека не может легко сосуществовать с ее библиотеками компонентов или другими библиотеками, которые зависят от этих библиотек компонентов.

Если в новом проекте вы ссылаетесь как на свою ILMerged lib, так и на устаревшую библиотеку, которая зависит от одного из входов, которые вы дали ILMerge, вы обнаружите, что вы не можете передавать какой-либо тип из ILMerged lib в любой метод в старой библиотеке без какого-либо сопоставления типов (например, автоматическое или ручное сопоставление). Это связано с тем, что после того, как все скомпилировано, типы эффективно квалифицируются с именем сборки.

Имена также будут сталкиваться, но вы можете исправить это, используя extern alias.

Мой совет будет состоять в том, чтобы избежать включения в объединенную сборку публично доступной библиотеки lib, которую предоставляет ваша объединенная сборка (например, с помощью типа возвращаемого значения, параметра метода/конструктора, поля, свойства, общего...), если вы точно не знаете, что пользователь вашей объединенной сборки не будет и никогда не будет зависеть от отдельно стоящей версии той же библиотеки.

Ответ 12

Мне кажется, что # 1 ILMerge Best Practice - это не использование ILMerge. Вместо этого используйте SmartAssembly. Одна из причин этого заключается в том, что лучшая практика №2 ILMerge - всегда запускать PEVerify после выполнения ILMerge, потому что ILMerge не гарантирует, что он правильно объединит сборки в действительный исполняемый файл.

Другие недостатки ILMerge:

  • при слиянии он разделяет XML-комментарии (если бы я об этом позаботился, я бы использовал инструмент обфускации)
  • он неправильно обрабатывает создание соответствующего файла .pdb

Еще один инструмент, на который стоит обратить внимание, - Mono.Cecil и инструмент Mono.Linker [2].

[2]: http://www.mono-project.com/Linker