Лучшие практики ILMerge
Вы используете ILMerge? Вы используете ILMerge для объединения нескольких сборок, чтобы упростить развертывание DLL? Обнаружили ли вы проблемы с развертыванием / управлением версиями в производственной среде после объединения сборок ILMerging?
Мне нужен совет относительно использования ILMerge для уменьшения трения при развертывании, если это вообще возможно.



Ответы 12
Мы используем ILMerge во многих проектах. Завод программного обеспечения веб-сервисов, например, производит на выходе что-то вроде 8 сборок. Мы объединяем все эти библиотеки DLL в одну, чтобы хост службы мог ссылаться только на одну DLL.
Это несколько облегчает жизнь, но и в этом нет ничего страшного.
Мы используем ILMerge в блоках приложений Microsoft — вместо 12 отдельных файлов DLL у нас есть один файл, который мы можем загрузить в наши клиентские области, плюс структура файловой системы намного лучше.
После объединения файлов мне пришлось отредактировать список проектов Visual Studio, удалить 12 отдельных сборок и добавить один файл в качестве ссылки, иначе он пожаловался бы, что не может найти конкретную сборку. Я не слишком уверен, как это будет работать при пост-развертывании, возможно, стоит попробовать.
Мы только начали использовать ILMerge в наших решениях, которые распространяются и используются в других наших проектах, и пока все идет хорошо. Вроде все нормально работает. Мы даже запутали упакованную сборку напрямую.
Мы планируем сделать то же самое со сборками MS Enterprise Library.
Единственная реальная проблема, с которой я сталкиваюсь, — это управление версиями отдельных сборок из пакета.
Я использую ILMerge почти для всех своих приложений. Я интегрировал его прямо в процесс сборки релиза, так что в итоге я получаю по одному exe на приложение без дополнительных dll.
Вы не можете использовать ILMerge для любых сборок C++, которые имеют собственный код. Вы также не можете использовать ILMerge для каких-либо сборок, содержащих XAML для WPF (по крайней мере, я не добился успеха с этим). Он жалуется во время выполнения, что ресурсы не могут быть обнаружены.
Я написал исполняемый файл оболочки для ILMerge, в котором я передаю имя запускаемого exe для проекта, который хочу объединить, и имя выходного exe, а затем оно отражает зависимые сборки и вызывает ILMerge с соответствующими параметрами командной строки. Теперь, когда я добавляю в проект новые сборки, это намного проще, мне не нужно помнить об обновлении скрипта сборки.
Как вы реализовали интеграцию сборки релиза?
Вот потенциальный обходной путь для ILMerge + XAML: richarddingwall.name/2009/05/14/…
@Lamar Не могли бы вы поделиться этой оболочкой .exe для ILMerge?
Мы столкнулись с проблемами при объединении библиотек DLL, ресурсы которых находятся в одном пространстве имен. В процессе слияния одно из пространств имен ресурсов было переименовано, и поэтому ресурсы не удалось найти. Может, мы просто что-то делаем не так, но все еще изучаем проблему.
Недавно у меня возникла проблема, когда я добавил сборку в сборку, у меня были некоторые классы, которые вызывались через отражение в CMS с открытым исходным кодом Umbraco.
Информация для выполнения вызова через отражение была взята из таблицы db, которая имела имя сборки и пространство имен реализованного класса и интерфейса. Проблема заключалась в том, что вызов отражения завершался ошибкой при слиянии dll, однако, если dll была отдельной, все работало нормально. Я думаю, проблема может быть похожа на ту, что у longeasy?
Мне кажется, что лучшая практика №1 ILMerge — не использовать ILMerge. Вместо этого используйте SmartAssembly. Одна из причин этого заключается в том, что лучший метод №2 ILMerge — всегда запускать PEVerify после выполнения ILMerge, потому что ILMerge не гарантирует, что он правильно объединит сборки в допустимый исполняемый файл.
Другие недостатки ILMerge:
- при слиянии он удаляет комментарии XML (если бы меня это волновало, я бы использовал инструмент обфускации)
- он неправильно обрабатывает создание соответствующего файла .pdb
Еще один инструмент, на который стоит обратить внимание, — это Mono.Cecil и Mono.Linker [2].
[2]: http: // www.mono-project.com/Linker
«он неправильно обрабатывает создание соответствующего файла .pdb» — при каких условиях это верно? Я наблюдал, как ILMerge генерирует объединенные pdb, и использовал их без проблем.
Если какая-либо из сборок, которые вы хотите объединить, еще не имеет .pdb. Кроме того, SmartAssembly правильно обрабатывает ресурсы WPF, такие как BAML.
Большим преимуществом ILMerge перед Smartassembly является то, что он объединяет файлы документации XML. Smartassembly не будет этого делать на момент публикации. — платный пользователь Smartassembly
Вступление
В этом посте показано, как заменить все .exe + .dll files одним combined .exe . Он также сохраняет нетронутым отладочный файл .pdb .
Для консольных приложений
Вот базовый Post Build String для Visual Studio 2010 SP1 с использованием .NET 4.0. Я создаю консоль .exe со всеми вложенными в нее файлами .dll.
Основные подсказки
- На выходе получается файл « AssemblyName.all.exe », который объединяет все вложенные DLL в один .exe.
- Обратите внимание на каталог ILMerge\ . Вам нужно либо скопировать утилиту ILMerge в каталог решения (чтобы вы могли распространять исходный код, не беспокоясь о документировании установки ILMerge), либо изменить этот путь, чтобы он указывал на то, где находится ILMerge.exe.
Дополнительные подсказки
Если у вас есть проблемы с тем, что он не работает, включите Output и выберите Show output from: Build . Проверьте точную команду, фактически созданную Visual Studio, и проверьте наличие ошибок.
Пример сценария сборки
Этот сценарий заменяет все .exe + .dll files одним combined .exe . Он также сохраняет нетронутым отладочный файл .pdb.
Чтобы использовать, вставьте это в свой шаг Post Build на вкладке Build Events в проекте C# и убедитесь, что вы настроили путь в первой строке, чтобы он указывал на ILMerge.exe :
Как вы показываете результат сборки? У меня тихая проблема с записью вывода. stackoverflow.com/questions/42301103/…
@octopusgrabbus В Visual Studio выберите View.. Output , выберите Build , и он покажет вывод командной строки из компилятора (включая шаги, описанные выше). Или скопируйте эти команды в файл .bat , а затем запустите его из окна DOS, чтобы увидеть результат.
Я знаю, что это старый вопрос, но мы используем ILMerge не только для уменьшения количества зависимостей, но и для интернализации «внутренних» зависимостей (например, automapper, restsharp и т. д.), Которые используются утилитой. Это означает, что они полностью абстрагированы, и проекту, использующему объединенную утилиту, не нужно о них знать. Это снова уменьшает количество необходимых ссылок в проекте и позволяет при необходимости использовать / обновлять собственную версию той же внешней библиотеки.
У нас была такая же проблема с объединением зависимостей WPF . Кажется, что ILMerge не справляется с этим. Costura.Fody, однако, отлично сработал для нас и заняло около 5 минут, чтобы начать . очень хороший опыт.
Просто установите с помощью Nuget (выбрав правильный проект по умолчанию в консоли диспетчера пакетов). Он вводится в целевой проект, и настройки по умолчанию сразу сработали для нас.
Он объединяет все библиотеки DLL, помеченные «Copy Local» = true, и создает объединенный .EXE (вместе со стандартным выводом), который хорошо сжат по размеру (намного меньше, чем общий размер вывода).
Лицензия MIT, поэтому вы можете изменять / распространять по мере необходимости.
Я только начинаю использовать ILMerge как часть моей сборки CI, чтобы объединить множество мелкозернистых контрактов WCF в единую библиотеку. Он работает очень хорошо, однако новая объединенная библиотека не может легко сосуществовать с ее библиотеками компонентов или другими библиотеками, которые зависят от этих библиотек компонентов.
Если в новом проекте вы ссылаетесь как на свою библиотеку ILMerged, так и на устаревшую библиотеку, которая зависит от одного из входных данных, которые вы передали в ILMerge, вы обнаружите, что не можете передать какой-либо тип из библиотеки ILMerged ни одному методу в устаревшая библиотека без какого-либо сопоставления типов (например, автоматического или ручного сопоставления). Это связано с тем, что после того, как все скомпилировано, типы эффективно квалифицируются именем сборки.
Имена также будут конфликтовать, но вы можете исправить это с помощью внешний псевдоним.
Я бы посоветовал избегать включения в вашу объединенную сборку любых общедоступных библиотек, которые предоставляет ваша объединенная сборка (например, через тип возвращаемого значения, параметр метода / конструктора, поле, свойство, общий . ), если вы не знаете наверняка, что пользователь ваша объединенная сборка не зависит и никогда не будет зависеть от отдельно стоящей версии той же библиотеки.
Обратите внимание, что для программ с графическим интерфейсом пользователя Windows (например, WinForms) вы захотите использовать переключатель / target: Winexe.
Ключ / target: EXE создает объединенное приложение консоль.
Собрать проект Visual Studio в один файл с помощью ILMerge
Обычно результатом компиляции проекта является сборка (assembly) проекта, а также его зависимости (Referenced Assemblies). Однако иногда нужно чтобы результатом был один файл единственный файл, независимый от других сборок. Например простая утилита, которую можно будет куда угодно скопировать и она будет работать.
Пример
Условно говоря после: Получаются:
Нам же нужно лишь один самодостаточный
То есть содержащий в себе dep1.dll и dep2.dll
На Хабре уже присутствует решение со встраиванием зависимостей в ресурсы, здесь я покажу как это сделать с помощью ILMerge и Post Build Event в Visual Studio.
Исходники
- github: github.com/gzvulon/ILMerge-Example
- Solution archive: github.com/gzvulon/ILMerge-Example/zipball/v1.0.0
- bat file: github.com/gzvulon/ILMerge-Example/blob/master/ILMerge/merge_all.bat
Инструменты
ILMerge — Программа от Microsoft Research, которая собственно и обладает требуемой функциональностью.
merge_all.bat — им мы воспользуемся в Post-build event.
Подготовка
Скачать и установить ILMerge.
Положить %PROGRAMFILES%\ILMerge\ILMerge.exe в папку $
Там же создать файл merge_all.bat
Добавить строчку в [Project->Properties->Build Events->Post-build event]:
«$(SolutionDir)\ILMerge\merge_all.bat» «$(SolutionDir)» «$(TargetPath)» $(ConfigurationName)
Содержание merge_all.bat
Все сборки из $output будут сливаться в одну. Если конфигурация Debug то в $output\Output, если Release то в результате в $output будет только один файл. Информация как прошло слияние и какие были проблемы пишется в Visual Studio Output. Комментарии объясняют, что происходит внутри. Например в данном случае происходит выбор платформы .NET 4.
Лицензия
С сайта ILMerge:
Commercial use permitted:
The language of ILMerge’s license has raised many questions. In a nutshell: commercial use is permitted, redistribution is not. Read the license carefully for full details since I am not (nor do I wish to be!) a lawyer.
То есть встраивать в процесс сборки можно, а распространять со своим продуктом — нельзя.
Лучшие практики ILMerge
Вы используете ILMerge? Вы используете ILMerge для объединения нескольких сборок, чтобы упростить развертывание DLL? Обнаружили ли вы проблемы с развертыванием / управлением версиями в производственной среде после объединения сборок ILMerging?
Мне нужен совет относительно использования ILMerge для уменьшения трения при развертывании, если это вообще возможно.
12 ответов
Я использую ILMerge почти для всех своих приложений. Я интегрировал его прямо в процесс сборки релиза, так что в итоге я получаю по одному exe на приложение без дополнительных dll.
Вы не можете использовать ILMerge для любых сборок C ++, которые имеют собственный код. Вы также не можете использовать ILMerge для каких-либо сборок, содержащих XAML для WPF (по крайней мере, я не добился успеха с этим). Он жалуется во время выполнения, что ресурсы не могут быть обнаружены.
Я написал исполняемый файл оболочки для ILMerge, в котором я передаю имя запускаемого exe для проекта, который хочу объединить, и имя выходного exe, а затем оно отражает зависимые сборки и вызывает ILMerge с соответствующими параметрами командной строки. Теперь, когда я добавляю в проект новые сборки, это намного проще, мне не нужно помнить об обновлении скрипта сборки.
Введение
В этом сообщении показано, как заменить все .exe + .dll files одним combined .exe . Он также сохраняет нетронутым файл отладки .pdb .
Для консольных приложений
Вот базовый Post Build String для Visual Studio 2010 SP1 с использованием .NET 4.0. Я создаю консоль .exe со всеми вложенными в нее файлами .dll.
Основные подсказки
- На выходе получается файл » AssemblyName.all.exe «, который объединяет все вложенные DLL в один .exe.
- Обратите внимание на каталог ILMerge\ . Вам нужно либо скопировать утилиту ILMerge в каталог решения (чтобы вы могли распространять исходный код, не беспокоясь о документировании установки ILMerge), либо изменить этот путь, чтобы он указывал на то, где находится ILMerge.exe.
Дополнительные подсказки
Если у вас возникли проблемы с тем, что он не работает, включите Output и выберите Show output from: Build . Проверьте точную команду, фактически созданную Visual Studio, и проверьте наличие ошибок.
Пример сценария сборки
Этот сценарий заменяет все .exe + .dll files одним combined .exe . Он также сохраняет нетронутым отладочный файл .pdb.
Чтобы использовать, вставьте это в свой шаг Post Build на вкладке Build Events в проекте C # и убедитесь, что вы настроили путь в первой строке так, чтобы он указывал на ILMerge.exe :
Мы столкнулись с проблемами при объединении библиотек DLL, ресурсы которых находятся в одном пространстве имен. В процессе слияния одно из пространств имен ресурсов было переименовано, и поэтому ресурсы не удалось найти. Может, мы просто что-то делаем не так, но все еще изучаем проблему.
Мы используем ILMerge в блоках приложений Microsoft — вместо 12 отдельных файлов DLL у нас есть один файл, который мы можем загрузить в наши клиентские области, плюс структура файловой системы намного лучше.
После объединения файлов мне пришлось отредактировать список проектов Visual Studio, удалить 12 отдельных сборок и добавить один файл в качестве ссылки, иначе он пожаловался бы, что не может найти конкретную сборку. Я не слишком уверен, как это будет работать при пост-развертывании, возможно, стоит попробовать.
Я знаю, что это старый вопрос, но мы используем ILMerge не только для уменьшения количества зависимостей, но и для интернализации «внутренних» зависимостей (например, automapper, restsharp и т. Д.), Которые используются утилитой. Это означает, что они полностью абстрагированы, и проекту, использующему объединенную утилиту, не нужно о них знать. Это снова уменьшает количество необходимых ссылок в проекте и позволяет при необходимости использовать / обновлять собственную версию той же внешней библиотеки.
Мы используем ILMerge во многих проектах. Завод программного обеспечения веб-сервисов, например, на выходе производит что-то вроде 8 сборок. Мы объединяем все эти библиотеки DLL в одну, чтобы хост службы мог ссылаться только на одну DLL.
Это несколько облегчает жизнь, но и в этом нет ничего страшного.
У нас была такая же проблема с объединением зависимостей WPF . Кажется, что ILMerge не справляется с этим. Costura.Fody, однако, отлично сработал для нас и заняло около 5 минут, чтобы начать . очень хороший опыт.
Просто установите с помощью Nuget (выбрав правильный проект по умолчанию в консоли диспетчера пакетов). Он вводится в целевой проект, и настройки по умолчанию сразу сработали для нас.
Он объединяет все библиотеки DLL, помеченные «Copy Local» = true, и создает объединенный .EXE (вместе со стандартным выводом), который хорошо сжат по размеру (намного меньше, чем общий размер вывода).
Лицензия MIT, поэтому вы можете изменять / распространять по мере необходимости.
Обратите внимание, что для программ с графическим интерфейсом пользователя Windows (например, WinForms) вы захотите использовать переключатель / target: winexe .
Параметр / target: exe создает объединенное приложение console .
Я только начинаю использовать ILMerge как часть моей сборки CI, чтобы объединить множество мелкозернистых контрактов WCF в единую библиотеку. Он работает очень хорошо, однако новая объединенная библиотека не может легко сосуществовать с ее библиотеками компонентов или другими библиотеками, которые зависят от этих библиотек компонентов.
Если в новом проекте вы ссылаетесь как на свою библиотеку ILMerged, так и на устаревшую библиотеку, которая зависит от одного из входных данных, которые вы передали в ILMerge, вы обнаружите, что не можете передать какой-либо тип из библиотеки ILMerged ни одному методу в устаревшая библиотека без какого-либо сопоставления типов (например, автоматического или ручного сопоставления). Это связано с тем, что после того, как все скомпилировано, типы эффективно квалифицируются именем сборки.
Имена также будут конфликтовать, но это можно исправить с помощью extern псевдоним.
Я бы посоветовал избегать включения в вашу объединенную сборку любой общедоступной библиотеки, которую предоставляет ваша объединенная сборка (например, через тип возвращаемого значения, параметр метода / конструктора, поле, свойство, общий . ), если вы не знаете наверняка, что пользователь ваша объединенная сборка не зависит и никогда не будет зависеть от отдельно стоящей версии той же библиотеки.
Мы только начали использовать ILMerge в наших решениях, которые распространяются и используются в других наших проектах, и пока все идет хорошо. Вроде все нормально работает. Мы даже запутали упакованную сборку напрямую.
Мы планируем сделать то же самое со сборками MS Enterprise Library.
Единственная реальная проблема, с которой я сталкиваюсь, — это управление версиями отдельных сборок из пакета.
Недавно у меня возникла проблема, когда я включил сборку в сборку, у меня были некоторые классы, которые вызывались через отражение в CMS с открытым исходным кодом Umbraco.
Информация для выполнения вызова через отражение была взята из таблицы db, которая имела имя сборки и пространство имен реализованного класса и интерфейса. Проблема заключалась в том, что вызов отражения завершался ошибкой при слиянии dll, однако, если dll была отдельной, все работало нормально. Я думаю, проблема может быть похожа на ту, что у longeasy?
Мне кажется, что лучшая практика №1 ILMerge — не использовать ILMerge. Вместо этого используйте SmartAssembly. Одна из причин этого заключается в том, что лучший метод №2 ILMerge — всегда запускать PEVerify после выполнения ILMerge, потому что ILMerge не гарантирует, что он правильно объединит сборки в допустимый исполняемый файл.