【问题标题】:How to Integrate ILMerge into Visual Studio Build Process to Merge Assemblies?如何将 ILMerge 集成到 Visual Studio 构建过程中以合并程序集?
【发布时间】:2011-02-03 02:30:53
【问题描述】:

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

我可以通过命令行使用 ILMerge 来完成此操作,但我想将这种引用程序集和项目的合并集成到 Visual Studio 项目中。从我的阅读中,我了解到我可以通过 MSBuild 任务或目标来执行此操作,然后将其添加到 C#/VB.NET 项目文件中,但我找不到具体的示例,因为 MSBuild 是一个大主题。此外,我发现了一些将 ILMerge 命令添加到 Post-build 事件的参考资料。

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

  2. 这与可能的 ILMerge.Targets 文件有何关联?

  3. 使用构建后事件会更好吗?

【问题讨论】:

标签: visual-studio visual-studio-2008 msbuild ilmerge


【解决方案1】:

通过添加以下代码编辑要合并的项目的 *.csproj 文件:

<Target Name="AfterBuild" Condition=" '$(ConfigurationName)' == 'Release' " BeforeTargets="PostBuildEvent">
  <CreateItem Include="@(ReferenceCopyLocalPaths)" Condition="'%(Extension)'=='.dll'">
    <Output ItemName="AssembliesToMerge" TaskParameter="Include" />
  </CreateItem>
  <Exec Command="&quot;$(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exe&quot; /internalize:&quot;$(MSBuildProjectPath)ilmerge.exclude&quot; /ndebug  /out:@(MainAssembly)  &quot;@(IntermediateAssembly)&quot; @(AssembliesToMerge->'&quot;%(FullPath)&quot;', ' ')" />
  <Delete Files="@(ReferenceCopyLocalPaths->'$(OutDir)%(DestinationSubDirectory)%(Filename)%(Extension)')" />
</Target>

注意事项:

  1. $(SolutionDir)packages\ILMerge.3.0.29\tools\net452\ILMerge.exe 替换为ILMerge.exe 所在的任何路径。
  2. 您可以删除目标中的 Condition 以在 Debug 上也进行合并,但调试器可能无法正常工作
  3. 如果您不排除任何可以删除的内容:/internalize:&amp;quot;$(MSBuildProjectPath)ilmerge.exclude&amp;quot;

【讨论】:

    【解决方案2】:

    这是一个很棒的article,它将向您展示如何将引用的程序集合并到输出程序集中。它准确地展示了如何使用 msbuild 合并程序集。

    【讨论】:

    【解决方案3】:

    MSBuild ILMerge task”(或MSBuild.ILMerge.Task)NuGet 包使此过程非常简单。它默认将任何“复制本地”引用合并到您的主程序集中。

    注意:虽然包名称相似,但这个与 Davide Icardi 在其answer 中提到的ILMerge.MSBuild.Tasks 不同。我在这里建议的版本是 2014 年 8 月首次发布的。

    【讨论】:

    • 应有的解决方案! +1
    • 这应该是公认的解决方案。让它真的无痛。谢谢!
    • 不错的一个:D 不完美,因为它“忘记”在输出目录中包含额外的文件,但仍然很好 ^^
    • 效果很好:包含包,构建,你就完成了!它是带有图标的on。
    • 我找不到任何有关 MSBuild ILMerge 的文档,我该如何使用它?有人有示例或说明吗?
    【解决方案4】:

    我的 2 美分 - 我收到了 @Jason 的回复,并使它适用于我的解决方案,我想在 bin/Debug 文件夹中生成 *.exe,所有 *.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 包版本中的。如果您有一些改进建议,请告诉我。

    【讨论】:

      【解决方案5】:

      这里有一个替代解决方案:

      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>
      

      3) 像往常一样构建您的项目。

      【讨论】:

      • 真是个坑,这个包维护得不好。我一直在使用它,但它缺少设置 TargetPlatform 的能力,这对 .NET 4.5/.NET 4.0 兼容很重要。
      • @davidlcardi 如何替换目标文件名、dll_to_merge 等
      • @Smith TargetFileName 已经是一个 msbuild 变量,因此您无需替换它。 LIB1_To_Merge.dll 是固定名称。可能使用一些更复杂的 msbuild 脚本可以找到所有引用的程序集,但我不知道该怎么做。
      • @DavideIcardi 请帮我看看你能不能回复这个stackoverflow.com/questions/15588086/…
      • 有没有办法以某种方式使用我的密钥文件让这个标志成为我的程序集?
      【解决方案6】:

      更多信息可能对某些实施Scott Hanselman's solution 的人有用。

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

      /lib:$(MSBuildBinPath)

      然后我发现 IlMerge 在合并时会挂起。它使用了一点 CPU 和大量 RAM,但没有输出任何东西。我找到了修复on stackoverflow of course

      /targetplatform:v4

      我还发现 Scott 的博客文章中使用的一些 MSBuild 属性依赖于从项目目录执行 MsBuild,因此我对其进行了一些调整。

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

      我最终用以下 Exec 元素替换了 Scott 原始文章中的元素:

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

      更新 我还发现 Logic Labs answer 关于保持 CopyLocal 行为,并且如果您使用 Nuget 包,则将 ilMerged 程序集从 CopyLocal 中排除是必不可少的。否则,您需要为未合并的引用程序集的每个包目录指定 /lib 参数。

      【讨论】:

      • 实际上我最终下载了 ILMerge.exe,将其添加到源代码管理并将一些命令写入构建后事件
      【解决方案7】:

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

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

      要解决这个问题 - 而不是:

      <Target Name="_CopyFilesMarkedCopyLocal"/> 
      

      将此条目添加到目标文件(仅限 .NET 3.5)(过滤掉非 ilmerge 复制本地文件,并将它们视为正常文件)

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

      【讨论】:

      • 哦,是的!如果您使用 Nuget,这绝对是必需的,否则您必须指定您未合并的每个引用程序集的包内容文件夹。谢谢!
      【解决方案8】:

      查看 Jomo 的这篇文章。他有一个快速的过程来破解 ILMerge 进入 msbuild 系统

      【讨论】:

      • hanselman.com/blog/… 上的文章 Mixing Languages in a Single Assembly in Visual Studio with ILMerge 和 MSBuild 是基于他的博客,并通过设置 ILMerge=True/False 增强了允许您选择性合并的技术在项目文件中。这篇文章比 Jomo 的博客条目详细得多。
      【解决方案9】:

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

      【讨论】:

      • 此代码存在问题,如果您不想 ILMerge 您的所有引用。见my answer
      猜你喜欢
      • 2012-07-31
      • 2014-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-03
      • 1970-01-01
      相关资源
      最近更新 更多