Обычно результатом компиляции проекта является сборка (assembly) проекта, а также его зависимости (Referenced Assemblies). Однако иногда нужно чтобы результатом был один файл единственный файл, независимый от других сборок. Например простая утилита, которую можно будет куда угодно скопировать и она будет работать.
Условно говоря после:
На Хабре уже присутствует решение со встраиванием зависимостей в ресурсы, здесь я покажу как это сделать с помощью ILMerge и Post Build Event в Visual Studio.
ILMerge — Программа от Microsoft Research, которая собственно и обладает требуемой функциональностью.
merge_all.bat — им мы воспользуемся в Post-build event.
Скачать и установить ILMerge.
Положить
Там же создать файл merge_all.bat
Добавить строчку в [Project->Properties->Build Events->Post-build event]:
Все сборки из $output будут сливаться в одну. Если конфигурация Debug то в $output\Output, если Release то в результате в $output будет только один файл. Информация как прошло слияние и какие были проблемы пишется в Visual Studio Output. Комментарии объясняют, что происходит внутри. Например в данном случае происходит выбор платформы .NET 4.
UPD:
С сайта 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.
То есть встраивать в процесс сборки можно, а распространять со своим продуктом — нельзя.
Открытым остался вопрос про лиценции объединяемых dll.
Пример
Условно говоря после:
compile App\App.csproj dir App\bin\ReleaseПолучаются:
App.exe dep1.dll dep2.dllНам же нужно лишь один самодостаточный
App.exeТо есть содержащий в себе
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
в папку ${SolutionDir}ILMerge\
Там же создать файл 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.
@ECHO OFF
rem # set .NET version and output folder name
set net="v4, C:\Windows\Microsoft.NET\Framework\v4.0.30319"
set output=Output
rem # process arguments
set ILMergeSolution=%1ILMerge\ILMerge.exe
rem # determine programm files of x86 for 32 and 64 Platform
IF EXIST "%PROGRAMFILES(x86)%" set prorgammFiles=%PROGRAMFILES(x86)%
IF NOT EXIST "%PROGRAMFILES(x86)%" set prorgammFiles=%PROGRAMFILES%
rem # if ILMerge.exe not in the $(SolutionDir)ILMerge\
rem # then try to use installed in prorgammFiles
IF EXIST %ILMergeSolution% set ILMerge="%ILMergeSolution%"
IF NOT EXIST %ILMergeSolution% set ILMerge=%prorgammFiles%\Microsoft\ILMerge\ILMerge.exe
set target_path=%2
set target_file=%~nx2
set target_dir=%~dp2
set ConfigurationName=%3
rem # set output path and result file path
set outdir=%target_dir%%output%
set result=%outdir%\%target_file%
rem # print info
@echo Start %ConfigurationName% Merging %target_file%.
@echo Target: %target_path%
@echo target_dir: %target_dir%
@echo Config: %ConfigurationName%
rem # recreate outdir
IF EXIST "%outdir%" rmdir /S /Q "%outdir%"
md "%outdir%"
rem # run merge cmd
@echo Merging: '"%ILMerge%" /wildcards /targetplatform:%net% /out:"%result%" %target_path% "%target_dir%*.dll"'
"%ILMerge%" /wildcards /targetplatform:%net% /out:"%result%" %target_path% "%target_dir%*.dll"
rem # if succeded
IF %ErrorLevel% EQU 0 (
rem # clear real output folder and put there result assembly
IF %ConfigurationName%==Release (
del %target_dir%*.*
del %target_dir%*.dll
del %target_dir%*.pdb
del %target_dir%*.xml
del %target_dir%*.*
copy %result% %target_dir%
rmdir /S /Q %outdir%
set result=%target_path%
@echo Result: %target_file% "-> %target_path%"
) ELSE (
@echo Result: %target_file% "-> %result%" )
set status=succeded
set errlvl=0
) ELSE (
set status=failed
set errlvl=1
)
@echo Merge %status%
exit %errlvl%
UPD:
Лицензия
С сайта 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.
То есть встраивать в процесс сборки можно, а распространять со своим продуктом — нельзя.
Открытым остался вопрос про лиценции объединяемых dll.
Минусы
- beliakov: ILMerge память жрет как бегемот… На большом количестве сборок
- braindamaged: игнорирует ключик, который заставляет её, в свою очередь, игнорировать сборки и неймспейсы, оказавшиеся в зависимостях.
Схожие инструменты
- aspnet_merge Для ASP.NET
- NGen Создает локальный кэш с dll
Материалы по теме
- Встраивание в ресурсы — habrahabr.ru/blogs/personal/67836
- As Visual Studio Project Target — http://www.hanselman.com/blog/MixingLanguag...
- Eще Target — http://blogs.clariusconsulting.net/kzu/how-to-merge-your-referenced-assemblies-into-the-output-assembly-for-improved-usability/
- Best practices — stackoverflow.com/questions/9376/ilmerge-best-practices
- Simplest .bat — peyotest.blogspot.com/2010/03/using-ilmerge-in-post-build-step.html
- Advanced .bat — www.tanguay.info/web2008/codeExample.php?id=671