如何将ILMerge集成到Visual Studio构建过程以合并程序集?

AMi*_*ico 74 msbuild ilmerge visual-studio-2008 visual-studio

我想将一个.NET DLL程序集和一个由VB.NET控制台应用程序项目引用的C#类库项目合并到一个命令行控制台可执行文件中.

我可以从命令行使用ILMerge执行此操作,但我希望将引用程序集和项目的这种合并集成到Visual Studio项目中.从我的阅读中,我了解到我可以通过MSBuild Task或Target执行此操作,只需将其添加到C#/ VB.NET项目文件中,但我找不到具体的示例,因为MSBuild是一个很大的主题.此外,我找到一些将ILMerge命令添加到Post-build事件的引用.

  1. 如何将ILMerge集成到Visual Studio(C#/ VB.NET)项目中,这些项目只是MSBuild项目,将所有引用的程序集(copy-local = true)合并到一个程序集中?

  2. 这如何与可能的ILMerge.Targets文件绑定?

  3. 使用Post-build事件会更好吗?

Hol*_*per 59

" MSBuild ILMerge任务 "(或MSBuild.ILMerge.Task)NuGet包使这个过程非常简单.它默认将任何"复制本地"引用合并到主程序集中.

注意:尽管这些软件包的名称相似,但这个名称与ILMerge.MSBuild.TasksDavide Icardi在其答案中提到的不同.我在这里建议的那个首次发布于2014年8月.

  • 应该是一个解决方案!+1 (3认同)
  • 我找不到 MSBuild ILMerge 的任何文档,我该如何使用它?有没有人有例子或说明? (2认同)

Jas*_*ett 18

更多信息可能对某些实施Scott Hanselman解决方案的人有用.

当我第一次设置它时,它会抱怨无法解析对System.Core等的引用.这与.NET 4支持有关.包含指向.NET 4 Framework目录的/ lib参数修复了它(实际上只包含$(MSBuildBinPath)).

/lib:$(MSBuildBinPath)

然后我发现IlMerge会在合并时挂起.它使用了一些CPU和大量的RAM,但没有输出任何东西.我当然找到了stackoverflow上的修复程序.

/targetplatform:v4

我还发现Scott的博客文章中使用的一些MSBuild属性依赖于从项目目录中执行MsBuild,所以我稍微调整了一下.

然后我将目标&ilmerge.exe移动到源代码树的tools文件夹中,这需要对路径进行另一个小调整...

我最终得到了以下Exec元素来替换Scott原始文章中的那个:

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

更新 我还发现逻辑实验室的答案是关于保持CopyLocal行为,如果您使用的是Nuget软件包,则只​​需从CopyLocal中排除ilMerged程序集.否则,您需要为未合并的引用程序集的每个程序包目录指定/ lib参数.


Dav*_*rdi 18

这是另一种解决方案:

1)从nuget安装ILMerge.MSBuild.Tasks包

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>
Run Code Online (Sandbox Code Playgroud)

3)像往常一样构建项目.


AMi*_*ico 15

文章将Visual Studio中的单个程序集中的语言与ILMerge和MSBuild无缝混合,网址http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx演示了如何在Visual Studio项目中使用ILMerge和MSBuild.


Log*_*abs 8

我在文章中找到了一个问题:http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx.

如果您有任何不希望ILMerge的引用,那么文章中的代码将失败,因为它会覆盖默认的CopyLocal行为以不执行任何操作.

解决这个问题 - 而不是:

<Target Name="_CopyFilesMarkedCopyLocal"/> 
Run Code Online (Sandbox Code Playgroud)

将此条目添加到目标文件中(仅限.NET 3.5)(过滤掉非ilmerge copylocal文件,并将其视为正常)

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