代码之家  ›  专栏  ›  技术社区  ›  AMissico

如何将ILMerge集成到VisualStudio生成过程中以合并程序集?

  •  69
  • AMissico  · 技术社区  · 16 年前

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

    我可以通过命令行中的ILMerge实现这一点,但是我希望将引用程序集和项目的合并集成到visualstudio项目中。从我的阅读中,我了解到我可以通过MSBuild任务或目标来实现这一点,只需将其添加到C#/VB.NET项目文件中即可,但我找不到具体的示例,因为MSBuild是一个大主题。此外,我还找到了一些将ILMerge命令添加到生成后事件的引用。

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

    2. 使用生成后事件是否更好?

    8 回复  |  直到 16 年前
        1
  •  67
  •   Community Mohan Dere    9 年前

    “这个” MSBuild ILMerge task MSBuild.ILMerge.Task

    虽然这些包有相似的名称,但这个不同于 ILMerge.MSBuild.Tasks 戴维德·伊卡尔迪在他的 answer . 我在这里建议的第一本是2014年8月出版的。

        2
  •  20
  •   Davide Icardi i3arnon    13 年前

    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) 像往常一样构建项目。

        3
  •  18
  •   Community Mohan Dere    9 年前

    更多的信息可能对一些人有用 Scott Hanselman's solution .

    这与.NET4支持有关。包含指向.NET4Framework目录的/lib参数可以修复它(实际上只包含$(MSBuildBinPath))。

    /lib:$(MSBuildBinPath)

    on stackoverflow of course .

    /targetplatform:v4

    我最终得到了以下结果 替换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 如果您使用的是Nuget包,那么关于保持CopyLocal行为和从CopyLocal中排除ilMerged程序集是必不可少的。否则,需要为未合并的引用程序集的每个包目录指定/lib参数。

        4
  •  16
  •   AMissico    16 年前
        5
  •  9
  •   Logic Labs    14 年前

    我发现这篇文章的一个问题是: http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx

    如果您有任何不希望ILMerge的引用,那么文章中的代码将失败,因为它将重写默认的CopyLocal行为而不执行任何操作。

    要解决此问题-而不是:

    <Target Name="_CopyFilesMarkedCopyLocal"/> 
    

    将此项添加到目标文件(仅限.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>
    
        6
  •  4
  •   takrl cck    9 年前

    article 这将向您展示如何将引用的程序集合并到输出程序集中。它确切地展示了如何使用msbuild合并程序集。

        7
  •  1
  •   rui    11 年前

    我的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包版本中的。如果你有什么改进的建议,请告诉我。

        8
  •  1
  •   N T    6 年前

    通过添加以下代码,编辑要合并的项目的*.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 在目标中也要在调试时合并,但调试器可能无法工作
    3. 如果您不排除任何可以删除的内容: /internalize:&quot;$(MSBuildProjectPath)ilmerge.exclude&quot;
        9
  •  0
  •   JaredPar    16 年前

    看看乔莫的这篇文章。他有一个很快的程序将ILMerge破解到msbuild系统中