Как интегрировать ILMerge в процесс сборки Visual Studio для объединения сборок?

Я хочу объединить одну сборку .NET DLL и один проект библиотеки классов С#, на который ссылается проект приложения консоли VB.NET, в один исполняемый файл консоли командной строки.

Я могу сделать это с помощью ILMerge из командной строки, но я хочу интегрировать это слияние ссылочных сборок и проектов в проект Visual Studio. Из моего чтения я понимаю, что могу это сделать с помощью задачи MSBuild или Target и просто добавить его в файл проекта С#/VB.NET, но я не могу найти конкретного примера, поскольку MSBuild - большая тема. Более того, я нахожу некоторые ссылки, которые добавляют команду ILMerge к событию Post-build.

  • Как интегрировать ILMerge в проект Visual Studio (С#/VB.NET), который является только проектами MSBuild, для объединения всех ссылочных ассемблеров (copy-local = true) в одну сборку?

  • Как это связано с возможным файлом ILMerge.Targets?

  • Лучше ли использовать событие Post-build?

Ответ 2

" задача MSMuuLMMgege" (или MSBuild.ILMerge.Task). Пакет NuGet делает этот процесс довольно простым. По умолчанию он объединяет любые "копии локальных" ссылок в вашу основную сборку.

Примечание.. Хотя пакеты имеют похожие имена, этот отличается от ILMerge.MSBuild.Tasks, о котором сказал Давиде Иарки в своем ответе . Тот, который я предлагаю здесь, был впервые опубликован в августе 2014 года.

Ответ 3

Дополнительная информация, которая может быть полезной для некоторых людей, реализующих решение Scott Hanselman.

Когда я впервые установил это, он жаловался бы на невозможность разрешить ссылки на System.Core и т.д. Это как-то связано с поддержкой .NET 4. Включение аргумента /lib, указывающего на каталог .NET 4 Framework, исправляет его (фактически просто включает $(MSBuildBinPath)).

/lib:$(MSBuildBinPath)

Затем я обнаружил, что IlMerge будет висеть при слиянии. Он использовал немного процессора и много оперативной памяти, но ничего не выводил. Я нашел исправление fooobar.com/questions/90973/....

/targetplatform:v4

Я также обнаружил, что некоторые из свойств MSBuild, используемых в статье блога Скотта, полагались на выполнение MsBuild из каталога проекта, поэтому я немного изменил их.

Затем я переместил цели и ilmerge.exe в папку инструментов нашего исходного дерева, которая потребовала еще одну небольшую настройку для путей...

Наконец, я получил следующий элемент Exec, чтобы заменить его в оригинальной статье Скотта:

<Exec Command="&quot;$(MSBuildThisFileDirectory)Ilmerge.exe&quot; /lib:$(MSBuildBinPath) /targetplatform:v4 /out:@(MainAssembly) &quot;$(MSBuildProjectDirectory)\@(IntermediateAssembly)&quot; @(IlmergeAssemblies->'&quot;%(FullPath)&quot;', ' ')" /> 

UPDATE Я также нашел ответ Logic Labs о сохранении поведения CopyLocal и просто исключая сборки ilMerged из CopyLocal, если вы используете пакеты Nuget. В противном случае вам нужно указать аргумент /lib для каждого каталога пакетов ссылочных сборок, которые не объединяются.

Ответ 4

Здесь альтернативное решение:

1) Установите пакет ILMerge.MSBuild.Tasks из nuget

PM > Установить пакет ILMerge.MSBuild.Tasks

2) Отредактируйте файл *.csproj проекта, который вы хотите объединить, добавив следующий код:

  <!-- Code to merge the assemblies into one:setup.exe -->
  <UsingTask TaskName="ILMerge.MSBuild.Tasks.ILMerge" AssemblyFile="$(SolutionDir)\packages\ILMerge.MSBuild.Tasks.1.0.0.3\tools\ILMerge.MSBuild.Tasks.dll" />
  <Target Name="AfterBuild">
    <ItemGroup>
      <MergeAsm Include="$(OutputPath)$(TargetFileName)" />
      <MergeAsm Include="$(OutputPath)LIB1_To_MERGE.dll" />
      <MergeAsm Include="$(OutputPath)LIB2_To_MERGE.dll" />
    </ItemGroup>
    <PropertyGroup>
      <MergedAssembly>$(ProjectDir)$(OutDir)MERGED_ASSEMBLY_NAME.exe</MergedAssembly>
    </PropertyGroup>
    <Message Text="ILMerge @(MergeAsm) -&gt; $(MergedAssembly)" Importance="high" />
    <ILMerge InputAssemblies="@(MergeAsm)" OutputFile="$(MergedAssembly)" TargetKind="SameAsPrimaryAssembly" />
  </Target>

3) Создайте свой проект, как обычно.

Ответ 5

Одна проблема, которую я нашел в статье: http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx.

Если у вас есть ссылки, которые вы не хотите ILMerge, тогда код в статье не будет выполнен, потому что он отменяет поведение по умолчанию CopyLocal, чтобы ничего не делать.

Чтобы исправить это - Вместо:

<Target Name="_CopyFilesMarkedCopyLocal"/> 

Вместо этого добавьте эту запись в файл целей (только для .NET 3.5) (чтобы отфильтровать ненулевые файлы копилалов и обработать их как обычно)

<Target Name="AfterResolveReferences">
    <Message Text="Filtering out ilmerge assemblies from ReferenceCopyLocalPaths" Importance="High" />
    <ItemGroup>
        <ReferenceCopyLocalPaths Remove="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.IlMerge)'=='true'" />
    </ItemGroup>
</Target>

Ответ 8

Мои 2 цента - я взял ответ @Jason и сделал это для моего решения, где я хотел создать *.exe в папке bin/Debug со всеми *.dll внутри той же папки.

<Exec Command="&quot;$(SolutionDir)packages\ILMerge.2.13.0307\Ilmerge.exe&quot; /wildcards /out:&quot;$(SolutionDir)..\$(TargetFileName)&quot; &quot;$(TargetPath)&quot; $(OutDir)*.dll" /> 

Примечание. Это решение явно жестко закодировано в версии пакета ILMerge nuget. Пожалуйста, дайте мне знать, если у вас есть предложения по улучшению.