代码之家  ›  专栏  ›  技术社区  ›  James Pogran

ilmerge最佳实践

  •  70
  • James Pogran  · 技术社区  · 16 年前

    你用ilmerge吗?是否使用ilmerge合并多个程序集以简化dll的部署?在将程序集集成到一起之后,您是否发现生产中的部署/版本控制存在问题?

    我正在寻找一些关于使用ilmerge来减少部署摩擦的建议,如果可能的话。

    12 回复  |  直到 7 年前
        1
  •  40
  •   Dinah SLaks    14 年前

    我几乎对所有不同的应用程序都使用ilmerge。我已经将它直接集成到发布构建过程中,所以我最终得到的是每个应用程序一个exe,没有额外的dll。

    不能使用任何具有本机代码的C++程序集ILMerge。 您也不能合并任何包含用于WPF的XAML的程序集(至少我还没有获得任何成功)。它在运行时抱怨找不到资源。

    我确实为ilmerge编写了一个包装可执行文件,在该文件中我传入了要合并的项目的启动exe名称和输出exe名称,然后它反映了依赖程序集,并使用适当的命令行参数调用ilmerge。当我向项目中添加新的程序集时,现在更容易了,我不需要记住更新构建脚本。

        2
  •  40
  •   Contango    8 年前

    介绍

    这篇文章展示了如何全部替换 .exe + .dll files 单用 combined .exe . 它还保持调试 .pdb 文件完整无缺。

    对于控制台应用程序

    这是基本的 Post Build String 对于Visual Studio 2010 SP1,使用.NET 4.0。我正在构建一个包含所有子.dll文件的console.exe。

    "$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
    

    基本提示

    • 输出是一个文件“ AssemblyName.all.exe “它将所有子DLL合并为一个.exe。
    • 注意到 ILMerge\ 目录。您需要将ilmerge实用程序复制到解决方案目录中(这样您就可以分发源代码,而无需担心记录ilmerge的安装),或者更改此路径以指向ilmerge.exe所在的位置。

    高级提示

    如果它不工作有问题,打开 Output 并选择 Show output from: Build . 检查Visual Studio实际生成的命令,并检查是否有错误。

    示例生成脚本

    此脚本将替换所有 .exe+.dll文件 单用 结合exe . 它还保持debugging.pdb文件的完整性。

    要使用,请将此粘贴到 Post Build 下步 Build Events 选项卡,并确保调整第一行中指向的路径 ILMerge.exe :

    rem Create a single .exe that combines the root .exe and all subassemblies.
    "$(SolutionDir)ILMerge\ILMerge.exe" /out:"$(TargetDir)$(TargetName).all.exe" "$(TargetDir)$(TargetName).exe" "$(TargetDir)*.dll" /target:exe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
    rem Remove all subassemblies.
    del *.dll
    rem Remove all .pdb files (except the new, combined pdb we just created).
    ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).all.pdb.temp"
    del *.pdb
    ren "$(TargetDir)$(TargetName).all.pdb.temp" "$(TargetName).all.pdb"
    rem Delete the original, non-combined .exe.
    del "$(TargetDir)$(TargetName).exe"
    rem Rename the combined .exe and .pdb to the original project name we started with.
    ren "$(TargetDir)$(TargetName).all.pdb" "$(TargetName).pdb"
    ren "$(TargetDir)$(TargetName).all.exe" "$(TargetName).exe"
    exit 0
    
        3
  •  10
  •   Surgical Coder    16 年前

    我们在Microsoft应用程序块上使用ilmerge,而不是12个单独的dll文件,我们只有一个文件可以上载到我们的客户端区域,而且文件系统结构非常整洁。

    合并文件后,我必须编辑Visual Studio项目列表,删除12个独立的关联,并添加单个文件作为引用,否则它会抱怨找不到特定的程序集。不过,我不太确定这在部署后如何工作,值得尝试一下。

        4
  •  6
  •   Mightymuke    12 年前

    我知道这是一个古老的问题,但我们不仅使用ilmerge来减少依赖项的数量,还可以将实用程序使用的“内部”依赖项(如automapper、restsharp等)内部化。这意味着它们是完全抽象的,使用合并的实用程序的项目不需要知道它们。这再次减少了项目中所需的引用,并允许它在需要时使用/更新同一外部库的自己版本。

        5
  •  3
  •   Esteban Araya    16 年前

    我们在很多项目中使用ilmerge。这个 Web Service Software Factory 例如,生成8个程序集作为其输出。我们将所有这些DLL合并到一个DLL中,这样服务主机就只需要引用一个DLL。

    它让生活变得更简单,但也不是什么大事。

        6
  •  3
  •   rexall    8 年前

    我们在组合WPF依赖项时遇到了同样的问题……Ilmerge似乎没有处理这些问题。科斯图拉。不过,福迪为我们工作得很好,大约花了5分钟的时间…非常好的经历。

    只需使用nuget安装(在包管理器控制台中选择正确的默认项目)。它将自己引入到目标项目中,默认设置立即为我们工作。

    它合并所有标记为“copy local”=true的DLL,并生成一个合并的.exe文件(与标准输出一起),该文件在大小上被很好地压缩(远小于总输出大小)。

    许可证是MIT,因此您可以根据需要修改/分发。

    https://github.com/Fody/Costura/

        7
  •  3
  •   dlchambers    7 年前

    请注意,对于Windows GUI程序(如WinForms),您需要使用/target: 威尼斯 开关。
    /目标: exe 开关创建合并 慰问 应用。

        8
  •  1
  •   Patrick    15 年前

    合并具有相同命名空间中资源的DLL时遇到问题。在合并过程中,其中一个资源命名空间被重命名,因此无法定位资源。也许我们只是在做错事,还在调查这个问题。

        9
  •  0
  •   markom    16 年前

    我们刚刚开始在我们的解决方案中使用ilmerge,这些解决方案被重新分配并用于我们的其他项目,目前为止还不错。一切似乎都正常。我们甚至直接混淆了包装好的组件。

    我们正在考虑对MS企业库程序集执行同样的操作。

    我看到的唯一真正的问题是包中各个程序集的版本控制。

        10
  •  0
  •   Ismail    14 年前

    我最近遇到了一个问题,我在程序集中合并了程序集,我有一些类,这些类是通过在Umbraco OpenSource CMS中的反射调用的。

    通过反射进行调用的信息来自具有实现的类的程序集名称和命名空间以及接口的DB表。问题是反射调用在合并dll时会失败,但是如果dll是单独的,那么一切都可以正常工作。我认为问题可能类似于龙易的问题?

        11
  •  0
  •   Steve Pick    8 年前

    我刚开始使用ilmerge作为我的CI构建的一部分,将许多细粒度的WCF契约组合到一个库中。它工作得很好,但是新合并的lib不能很容易地与其组件库或依赖于这些组件库的其他lib共存。

    如果在新项目中同时引用ILmerged库和依赖于向ILmerge提供的某个输入的旧库,则会发现在不进行某种类型映射(例如automapper或手动映射)的情况下,无法将任何类型从ILmerged库传递到旧库中的任何方法。这是因为一旦编译了所有内容,类型就可以有效地用程序集名称限定。

    名称也会发生冲突,但可以使用 extern alias .

    我的建议是避免在合并的程序集中包含合并程序集公开的任何公共可用的lib(例如,通过返回类型、方法/构造函数参数、字段、属性、泛型…),除非您确定合并程序集的用户不依赖于同一个库的独立版本,并且永远也不会依赖于该库的独立版本。

        12
  •  -1
  •   user429921    14 年前

    在我看来,Ilmerge的最佳实践是不要使用Ilmerge。相反,使用 SmartAssembly . 这样做的一个原因是2 ilmerge最佳实践是在执行ilmerge之后始终运行peverify,因为ilmerge不能保证将程序集正确合并到有效的可执行文件中。

    其他Ilmerge缺点:

    • 在合并时,它会去掉XML注释(如果我关心这一点,我会使用一个模糊工具)
    • 它不能正确处理创建相应的.pdb文件

    另一个值得注意的工具是mono.cecil和mono.linker[2]工具。

    【2】:http://www.mono-project.com/linker