.NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖

栏目: 编程工具 · 发布时间: 5年前

内容简介:我们有多种工具可以将程序集合并成为一个。比如 ILMerge、Mono.Merge。前者不可定制、运行缓慢、消耗资源(不过好消息是现在开源了);后者已被弃用、不受支持且基于旧版本的 Mono.Cecil。而本文介绍用来替代它们的 ILRepack,使用 ILRepack 来合并程序集。ILRepack 提供了可供你项目使用的 NuGet 包。如果你在团队项目当中安装了 ILRepack 的 NuGet 包,那么无论团队其他人是否安装了 ILRepack 的工具,都可以使用 ILRepack 工具。这可以避免

我们有多种 工具 可以将程序集合并成为一个。比如 ILMerge、Mono.Merge。前者不可定制、运行缓慢、消耗资源(不过好消息是现在开源了);后者已被弃用、不受支持且基于旧版本的 Mono.Cecil。

而本文介绍用来替代它们的 ILRepack,使用 ILRepack 来合并程序集。

以 NuGet 包的形式使用 ILRepack

ILRepack 提供了可供你项目使用的 NuGet 包。如果你在团队项目当中安装了 ILRepack 的 NuGet 包,那么无论团队其他人是否安装了 ILRepack 的工具,都可以使用 ILRepack 工具。这可以避免要求团队所有成员安装工具或者将工具内置到项目的源代码管理中。

要以 NuGet 包的形式来使用 ILRepack,需要首先安装 ILRepack 的 NuGet 包:

  • [NuGet Gallery ILRepack](https://www.nuget.org/packages/ILRepack/)

或者直接在你的项目的 csproj 文件中添加 PackageReference

<ItemGroup>
    <PackageReference Include="ILRepack" Version="2.0.17" />
</ItemGroup>

我现在有一个项目 Walterlv.Demo.AssemblyLoading,这是一个控制台程序。这个程序引用了一个 NuGet 包 Ben.Demystifier。为此带来了三个额外的依赖。

- Walterlv.Demo.AssemblyLoading.exe
- Ben.Demystifier.dll
- System.Collections.Immutable.dll
- System.Reflection.Metadata.dll

而我们可以使用 ILRepack 将这些依赖和我们生成的主程序合并成一个程序集,这样分发程序的时候只需要一个程序集即可。

那么,我们现在需要编辑我们的项目文件:

<Project Sdk="Microsoft.NET.Sdk">

        <PropertyGroup>
            <OutputType>Exe</OutputType>
            <TargetFramework>net48</TargetFramework>
        </PropertyGroup>
        
        <ItemGroup>
            <PackageReference Include="Ben.Demystifier" Version="0.1.4" />
            <PackageReference Include="ILRepack" Version="2.0.17" />
        </ItemGroup>

++      <Target Name="ILRepack">
++          <Exec Command=""$(ILRepack)" /out:$(OutputPath)$(AssemblyName).exe $(OutputPath)$(AssemblyName).exe $(OutputPath)Ben.Demystifier.dll $(OutputPath)System.Collections.Immutable.dll $(OutputPath)System.Reflection.Metadata.dll" />
++      </Target>
    
    </Project>

我们只增加了三行,添加了一个名称为 ILRepack 的 Target。(注意到项目文件中我有额外引用一个其他的 NuGet 包 Ben.Demystifier,这是为了演示将依赖进行合并而添加的 NuGet 包,具体是什么都没有关系,我们只是在演示依赖的合并。)在这个 Target 里面,我们使用 Exec 的 Task 来执行 ILRepack 命令。具体这个命令代表的含义我们在下一节介绍 ILRepack 工具的时候会详细介绍。如果你希望在你的项目当中进行尝试,可以把后面那些代表程序集的名称改为你自己项目中依赖程序集的名称。

现在在编译的时候使用命令 msbuild /t:ILRepack 就可以完成程序集的合并了。

注意,你普通编译的话是不会进行 IL 合并的。

如果你希望常规编译也可以进行 IL 合并,或者说希望在 Visual Studio 里面点击生成按钮的时候也能完成 IL 合并的话,那么你还需要增加一个跳板的编译目标 Target。

我将这个名为 _ProjectRemoveDependencyFiles 的 Target 增加到了下面。它的目的是在 AfterBuild 这个编译目标完成之后(AfterTargets)执行,然后执行前需要先执行(DependsOnTargets)ILRepack 这个 Target。在这个编译目标执行的时候还会将原本的三个依赖删除掉,这样在生成的目录下我们将只会看到我们最终期望的程序集 Walterlv.Demo.AssemblyLoading.exe 而没有其他依赖程序集。

<Project Sdk="Microsoft.NET.Sdk">

        <PropertyGroup>
            <OutputType>Exe</OutputType>
            <TargetFramework>net48</TargetFramework>
        </PropertyGroup>

        <ItemGroup>
            <PackageReference Include="Ben.Demystifier" Version="0.1.4" />
            <PackageReference Include="ILRepack" Version="2.0.17" />
        </ItemGroup>

        <Target Name="ILRepack">
            <Exec Command=""$(ILRepack)" /out:$(OutputPath)$(AssemblyName).exe $(OutputPath)$(AssemblyName).exe $(OutputPath)Ben.Demystifier.dll $(OutputPath)System.Collections.Immutable.dll $(OutputPath)System.Reflection.Metadata.dll" />
        </Target>

++      <Target Name="_ProjectRemoveDependencyFiles" AfterTargets="AfterBuild" DependsOnTargets="ILRepack">
++          <ItemGroup>
++              <_ProjectDependencyFile Include="$(OutputPath)Ben.Demystifier.dll" />
++              <_ProjectDependencyFile Include="$(OutputPath)System.Collections.Immutable.dll" />
++              <_ProjectDependencyFile Include="$(OutputPath)System.Reflection.Metadata.dll" />
++              </ItemGroup>
++          <Delete Files="@(_ProjectDependencyFile)" />
++      </Target>

    </Project>

最终生成的输出目录下只有我们最终期望生成的程序集:

.NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖

ILRepack 的命令行使用

相比于 ILMerge,ILRepack 的命令行在尽量贴近 ILMerge 的情况下做得更加简化了。

ilrepack /out:Walterlv.Demo.AssemblyLoading.exe Walterlv.Demo.AssemblyLoading.exe Ben.Demystifier.dll System.Collections.Immutable.dll System.Reflection.Metadata.dll

其中, /out 表示最终的输出程序集的名称或路径,后面没有前缀的参数都是需要合并的程序集的名称或路径。这些需要合并的参数中,第一个参数是主程序集,而后续其他的都是待合并的程序集。区别主程序集和其他程序集的原因是输出的程序集需要有名称、版本号等等信息,而这些信息将使用主程序集中的信息。

如果希望使用 ILRepack 的其他命令,可以考虑使用帮助命令:

ilrepack /help

或者直接访问 ILRepack 的 GitHub 仓库来查看用法:

参考资料


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Masterminds of Programming

Masterminds of Programming

Federico Biancuzzi、Chromatic / O'Reilly Media / 2009-03-27 / USD 39.99

Description Masterminds of Programming features exclusive interviews with the creators of several historic and highly influential programming languages. Think along with Adin D. Falkoff (APL), Jame......一起来看看 《Masterminds of Programming》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

MD5 加密
MD5 加密

MD5 加密工具

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器