Комментарии 29
Не совсем понял, есть ли возможность включения в сборку .net runtime и запуска приложение на ОС, где .net не установлен. Если такой возможности нет, то особой пользы от ILMerge не вижу.
Польза в том, что все либы будут внутри. Если у вас небольшая утилита, то не придётся таскать всегда с собой разные либы.
Также это полезно большим проектам, где 100500 dll-ок. После смерживания они(проекты) шевелятся заметно шустрее.
Также это полезно большим проектам, где 100500 dll-ок. После смерживания они(проекты) шевелятся заметно шустрее.
Лучше при установке NGen'ом по этим сборкам пройтись, а не валить все в одну кучу. Обновляться потом печально будет.
а насколько быстрее? буду благодарен за какое-нибудь сравнение
Весь .NET встроить не получиться. Но если нужна маленькая утилита и вы решили ее написать на .NET, но хотите чтобы она была в одном файле то тогда подойдет.
Или если библиотеку собрать в один dll, а не таскать кучу зависимостей.
Или если библиотеку собрать в один dll, а не таскать кучу зависимостей.
Можно задать возможно глупый вопрос, а что происходит в момент запуска приложения и в момент вызова функции из библиотеки? Т.е. библиотеки сохраняют все свойства и просто находят в одном файле или они в какой-то момент экспортируются в отдельные файлы?
Я точно не знаю принцип работы ILMerge,
но судя по dotPeek (Reflector от JetBrains)
он сливает все namespace с классами в одну dll,
видимо разрешая имена классов и вызовы функций в рамках одной dll.
Соответсвенно:
IMHO при загрузке этой dll, загружается все необходимое пространство имен.
но судя по dotPeek (Reflector от JetBrains)
он сливает все namespace с классами в одну dll,
видимо разрешая имена классов и вызовы функций в рамках одной dll.
Соответсвенно:
IMHO при загрузке этой dll, загружается все необходимое пространство имен.
ILMerge может поломать вам Reflection, ибо если мержатся сборки с одинаковыми именами классов и неймспейсами (приватные бывает совпадают), их переименуют.
Хороша софтинка ILMerge, но при использовании её натолкнулся на неприятную, хоть и мелкую, багу: она игнорирует ключик, который заставляет её, в свою очередь, игнорировать сборки и неймспейсы, оказавшиеся в зависимостях. Проблему обошли, в итоге, но время потратили.
Ниасилил EULA этой утилиты. Ее вообще можно в коммерческих целях применять?
С сайта 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.
То есть встраивать в процесс сборки можно, а распространять со своим продуктом — нельзя.
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.
То есть встраивать в процесс сборки можно, а распространять со своим продуктом — нельзя.
Ok, с этим понятно. Другой спорный момент. Лицензии сторонних компонент часто содержат запрет на декомпиляцию. А ILMerge похоже занимается именно этим — декомпилирует сборки и заново собирает в один файл, так?
Может, конечно, спрошу глупость, но зачем нужен пункт
«Положить %PROGRAMFILES%\ILMerge\ILMerge.exe в папку ${SolutionDir}ILMerge\»
Неужели оно не будет работать (или будет криво работать) если оставить где есть, а в PATH дописать что там искать тоже, ну и в батнике написать ILMerge.exe без всяких абсолютных путей?
«Положить %PROGRAMFILES%\ILMerge\ILMerge.exe в папку ${SolutionDir}ILMerge\»
Неужели оно не будет работать (или будет криво работать) если оставить где есть, а в PATH дописать что там искать тоже, ну и в батнике написать ILMerge.exe без всяких абсолютных путей?
Если в PATH то будет.
Но в мою задачу входило придумать решение для source control,
так чтобы если солюшн скачивается из source control на очередной машине,
то нет необходимости лезть в PATH. Нажал build и все.
Правда ILMerge.exe и merge_all.bat надо еще в директорию солюшена закинуть в VS.
Просто ILMerge.exe не будет, тк текущая папка это папка проекта.
Но в мою задачу входило придумать решение для source control,
так чтобы если солюшн скачивается из source control на очередной машине,
то нет необходимости лезть в PATH. Нажал build и все.
Правда ILMerge.exe и merge_all.bat надо еще в директорию солюшена закинуть в VS.
Просто ILMerge.exe не будет, тк текущая папка это папка проекта.
есть ещё aspnet_merge которая работает через ILMerge
ILMerge память жрет как бегемот… На большом количестве сборок вылетает с System.OutOfMemoryException.
Вот мой выход. Можно было завернуть в отдельный подгужаемый таск-файл, но я не стал заморачивтся — нужно было в одном месте.
<Target Name="AfterBuild">
<ItemGroup>
<OutputFiles Include="$(TargetDir)\*.dll" />
</ItemGroup>
<PropertyGroup>
<BinOutput>$(SolutionDir)..\bin\$(Configuration)</BinOutput>
</PropertyGroup>
<MakeDir Directories="$(BinOutput)" />
<Exec WorkingDirectory="$(TargetDir)" Command="$(SolutionDir)\..\Alien\ILMerge.exe /target:library /out:$(BinOutput)\$(TargetFileName).dll /targetplatform:v4,$(MSBuildBinPath) @(OutputFiles, ' ')" />
</Target>
* This source code was highlighted with Source Code Highlighter.
Спасибо за пример. До не мог понять как подступиться к ms build.
я взял его за базу и добавив экранирования путей закончил следующим:
я взял его за базу и добавив экранирования путей закончил следующим:
<!-- ILMerge Step -->
<Target Name="AfterBuild">
<PropertyGroup >
<ILMerge_Solution>$(SolutionDir)ILMerge\ILMerge.exe</ILMerge_Solution>
<Programfiles>C:\Program Files (x86)\</Programfiles>
<Programfiles Condition="!Exists('$(Programfiles)')">C:\Program Files\</Programfiles>
<ILMerge_Installed>$(Programfiles)Microsoft\ILMerge\ILMerge.exe</ILMerge_Installed>
<ErrorMesssage>ILMerge is not found here: '$(ILMerge_Solution)', nor here: '$(ILMerge_Installed)'</ErrorMesssage>
<ILMerge>NOTSET</ILMerge>
<ILMerge Condition="Exists('$(ILMerge_Installed)')">"$(ILMerge_Installed)"</ILMerge>
<ILMerge Condition="Exists('$(ILMerge_Solution)')">"$(SolutionILMerge)"</ILMerge>
</PropertyGroup>
<Error Condition=" '$(ILMerge)' == 'NOTSET' " Text="Please Install ILMerge. $(ErrorMesssage)" />
<ItemGroup>
<OutputDlls Include="$(TargetDir)*.dll" />
<OutputExes Include="$(TargetDir)*.exe" />
</ItemGroup>
<PropertyGroup>
<BinOutput>$(TargetDir)merged\</BinOutput>
<TargetFilePath>"$(BinOutput)$(TargetFileName)"</TargetFilePath>
<OutputFiles>@(OutputExes->'"%(identity)"', ' ') @(OutputDlls->'"%(identity)"', ' ') </OutputFiles>
</PropertyGroup>
<MakeDir Directories="$(BinOutput)" />
<Exec WorkingDirectory="$(TargetDir)" Command='$(ILMerge) /out:$(TargetFilePath) $(OutputFiles) /targetplatform:v4,$(MSBuildBinPath) ' />
</Target>
* This source code was highlighted with Source Code Highlighter.
Мелкий штрих: MsBuild подцепляет системные переменные как свои, то-есть нет необходимости объявлять Programfiles явно: в любом случае будут доступны
Ну и для полной красоты, чтобы не мешатся с AfterBuild-ами, можно поместить этот таржет в отдельний файл, присвоить ему (таржету) собственное имя, по соглашению начинающееся с подчеркивания, и перегрузить переменную BuildDependsOn:
$(ProgramFiles)
, и, если есть, $(ProgramFiles(x86))
. Вам же нужен всегда 32-битный Program Files, в MsBuild есть специальная зарезервированая переменная для этого: $(MSBuildProgramFiles32)
.Ну и для полной красоты, чтобы не мешатся с AfterBuild-ами, можно поместить этот таржет в отдельний файл, присвоить ему (таржету) собственное имя, по соглашению начинающееся с подчеркивания, и перегрузить переменную BuildDependsOn:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildDependsOn>
$(BuildDependsOn);_IlMergeOutput
</BuildDependsOn>
</PropertyGroup>
<Target Name="_IlMergeOutput">
...
</Target>
</Project>
* This source code was highlighted with Source Code Highlighter.
Как-то так. Тогда в результирующий *.*proj файл достаточно будет добавить одну строку импорта, а AfterBuild-ы можно будет оставить для других использований.Отлично, не знал $(MSBuildProgramFiles32).
Кстати судя по ссылке она называется $(MSBuildExtensionsPath32).
За завершающий штрих спасибо, так уже будет готовое решение.
Не вы не знаете есть ли в переменных среды windows что-то типа %MSBuildExtensionsPath32%?
Кстати судя по ссылке она называется $(MSBuildExtensionsPath32).
За завершающий штрих спасибо, так уже будет готовое решение.
Не вы не знаете есть ли в переменных среды windows что-то типа %MSBuildExtensionsPath32%?
Если вы используете .NET 4, то лучше пойти другим путем. Мы в своем проекте нахлебались от ILMerge, после перехода на AppDomain.CurrentDomain.AssemblyResolve — никаких проблем. И главное — никаких EULA.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Собрать проект Visual Studio в один файл с помощью ILMerge