ILMerge 最佳实践
你用ILMerge吗? 您是否使用 ILMerge 合并多个程序集以简化 dll 的部署? 在将程序集合并在一起后,您是否发现生产中的部署/版本控制存在问题?
我正在寻找一些有关使用 ILMerge 减少部署摩擦的建议(如果可能的话)。
Do you use ILMerge? Do you use ILMerge to merge multiple assemblies to ease deployment of dll's? Have you found problems with deployment/versioning in production after ILMerging assemblies together?
I'm looking for some advice in regards to using ILMerge to reduce deployment friction, if that is even possible.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
我们在 Microsoft 应用程序块上使用 ILMerge - 我们有一个可以上传到客户区域的文件,而不是 12 个单独的 DLL 文件,而且文件系统结构更加整洁。
合并文件后,我必须编辑 Visual Studio 项目列表,删除 12 个单独的程序集并添加单个文件作为参考,否则它会抱怨找不到特定的程序集。 我不太确定这在部署后会如何工作,但可能值得一试。
We use ILMerge on the Microsoft application blocks - instead of 12 seperate DLL files, we have a single file that we can upload to our client areas, plus the file system structure is alot neater.
After merging the files, I had to edit the visual studio project list, remove the 12 seperate assmeblies and add the single file as a reference, otherwise it would complain that it couldnt find the specific assembly. Im not too sure how this would work on post deployment though, could be worth giving it a try.
我知道这是一个老问题,但我们不仅使用 ILMerge 来减少依赖项的数量,而且还内部化实用程序使用的“内部”依赖项(例如 automapper、restsharp 等)。 这意味着它们被完全抽象出来,并且使用合并实用程序的项目不需要了解它们。 这再次减少了项目中所需的引用,并允许它在需要时使用/更新同一外部库的自己版本。
I know this is an old question, but we not only use ILMerge to reduce the number of dependencies but also to internalise the "internal" dependencies (eg automapper, restsharp, etc) that are used by the utility. This means they are completely abstracted away, and the project using the merged utility doesn't need to know about them. This again reduces the required references in the project, and allows it to use / update its own version of the same external library if required.
我们在很多项目中使用 ILMerge。 例如,Web 服务软件工厂 会生成类似 8 个程序集的内容作为其输出。 我们将所有这些 DLL 合并到一个 DLL 中,以便服务主机只需引用一个 DLL。
它让生活变得更轻松,但这也没什么大不了的。
We use ILMerge on quite a few projects. The Web Service Software Factory, for example produces something like 8 assemblies as its output. We merge all of those DLLs into a single DLL so that the service host will only have to reference one DLL.
It makes life somewhat easier, but it's not a big deal either.
当合并具有相同命名空间的资源的 DLL 时,我们遇到了问题。 在合并过程中,资源名称空间之一被重命名,因此无法找到资源。 也许我们只是在那里做错了什么,仍在调查这个问题。
We ran into problems when merging DLLs that have resources in the same namespace. In the merging process one of the resource namespaces was renamed and thus the resources couldn't be located. Maybe we're just doing something wrong there, still investigating the issue.
我们在组合 WPF 依赖项时遇到了同样的问题......ILMerge 似乎无法处理这些问题。 Costura.Fody 对我们来说工作得很好,花了大约 5 分钟才开始……这是一次非常好的体验。
只需使用 Nuget 进行安装(在包管理器控制台中选择正确的默认项目)。 它将自己引入到目标项目中,默认设置立即为我们工作。
它合并所有标记为“Copy Local”= true 的 DLL,并生成合并的 .EXE(与标准输出一起),其大小得到很好的压缩(远小于总输出大小)。
该许可证是 MIT 的,因此您可以根据需要修改/分发。
https://github.com/Fody/Costura/
We had the same problem with combining WPF dependencies .... ILMerge doesn't appear to deal with these. Costura.Fody worked perfectly for us however and took about 5 minutes to get going... a very good experience.
Just install with Nuget (selecting the correct default project in the Package Manager Console). It introduces itself into the target project and the default settings worked immediately for us.
It merges the all DLLs marked "Copy Local" = true and produces a merged .EXE (alongside the standard output), which is nicely compressed in size (much less than the total output size).
The license is MIT as so you can modify/distribute as required.
https://github.com/Fody/Costura/
请注意,对于 Windows GUI 程序(例如 WinForms),您需要使用 /target:winexe 开关。
/target:exe 开关创建一个合并的控制台应用程序。
Note that for windows GUI programs (eg WinForms) you'll want to use the /target:winexe switch.
The /target:exe switch creates a merged console application.
我刚刚开始使用 ILMerge 作为 CI 构建的一部分,将大量细粒度的 WCF 合约组合到一个库中。 它工作得很好,但是新的合并库无法轻松与其组件库或依赖于这些组件库的其他库共存。
如果在新项目中,您既引用了 ILMerged 库,又引用了依赖于您提供给 ILMerged 的输入之一的遗留库,您会发现无法将任何类型从 ILMerged 库传递到中的任何方法。遗留库而不进行某种类型映射(例如自动映射器或手动映射)。 这是因为一旦编译完所有内容,类型就可以使用程序集名称进行有效限定。
名称也会发生冲突,但您可以使用 extern 修复该问题别名。
我的建议是避免在合并程序集中包含合并程序集公开的任何公开可用的库(例如通过返回类型、方法/构造函数参数、字段、属性、泛型...),除非您确定用户您的合并程序集不会也永远不会依赖于同一库的独立版本。
I'm just starting out using ILMerge as part of my CI build to combine a lot of finely grained WCF contracts into a single library. It works very well, however the new merged lib can't easily co-exist with its component libraries, or other libs that depend on those component libraries.
If, in a new project, you reference both your ILMerged lib and also a legacy library that depends on one of the inputs you gave to ILMerge, you'll find that you can't pass any type from the ILMerged lib to any method in the legacy library without doing some sort of type mapping (e.g. automapper or manual mapping). This is because once everything's compiled, the types are effectively qualified with an assembly name.
The names will also collide but you can fix that using extern alias.
My advice would be to avoid including in your merged assembly any publicly available lib that your merged assembly exposes (e.g. via a return type, method/constructor parameter, field, property, generic...) unless you know for sure that the user of your merged assembly does not and will never depend on the free-standing version of the same library.
我几乎将 ILMerge 用于所有不同的应用程序。 我将其集成到发布构建过程中,因此我最终得到的是每个应用程序一个 exe,没有额外的 dll。
您无法 ILMerge 任何具有本机代码的 C++ 程序集。
您也无法 ILMerge 任何包含 WPF XAML 的程序集(至少我在这方面没有取得任何成功)。 它在运行时抱怨无法找到资源。
我确实为 ILMerge 编写了一个包装器可执行文件,其中传入要合并的项目的启动 exe 名称和输出 exe 名称,然后它反映依赖程序集并使用适当的命令行参数调用 ILMerge。 现在,当我向项目添加新程序集时,事情变得容易多了,我不必记住更新构建脚本。
I use ILMerge for almost all of my different applications. I have it integrated right into the release build process so what I end up with is one exe per application with no extra dll's.
You can't ILMerge any C++ assemblies that have native code.
You also can't ILMerge any assemblies that contain XAML for WPF (at least I haven't had any success with that). It complains at runtime that the resources cannot be located.
I did write a wrapper executable for ILMerge where I pass in the startup exe name for the project I want to merge, and an output exe name, and then it reflects the dependent assemblies and calls ILMerge with the appropriate command line parameters. It is much easier now when I add new assemblies to the project, I don't have to remember to update the build script.
我最近遇到了一个问题,我在程序集中合并了程序集,我有一些类,这些类是通过 Umbraco 开源 CMS 中的反射调用的。
通过反射进行调用的信息取自数据库表,该表具有程序集名称以及实现的类和接口的命名空间。 问题是,当 dll 合并时,反射调用会失败,但是如果 dll 是单独的,则一切正常。 我认为问题可能与 longeasy 遇到的问题类似?
I recently had issue where I had ilmerged assembly in the assembly i had some classes these were being called via reflection in Umbraco opensource CMS.
The information to make the call via reflection was taken from db table that had assembly name and namespace of class that implemented and interface. The issue was that the reflection call would fail when dll was il merged however if dll was separate it all worked fine. I think issue may be similar to the one longeasy is having?
我们刚刚开始在我们的解决方案中使用 ILMerge,这些解决方案已重新分发并在我们的其他项目中使用,到目前为止一切顺利。 一切似乎都正常。 我们甚至直接对打包的程序集进行了混淆。
我们正在考虑对 MS Enterprise Library 程序集执行相同的操作。
我看到的唯一真正的问题是包中各个程序集的版本控制。
We just started using ILMerge in our solutions that are redistributed and used in our other projects and so far so good. Everything seems to work okay. We even obfuscated the packaged assembly directly.
We are considering doing the same with the MS Enterprise Library assemblies.
The only real issue I see with it is versioning of individual assemblies from the package.
在我看来,#1 ILMerge 最佳实践是不要使用 ILMerge。 相反,请使用 SmartAssembly。 原因之一是,#2 ILMerge 最佳实践是在执行 ILMerge 后始终运行 PEVerify,因为 ILMerge 不保证它将正确地将程序集合并到有效的可执行文件中。
ILMerge 的其他缺点:
另一个值得关注的工具是 Mono.Cecil 和 Mono .链接器[2]工具。
[2]:http://www.mono-project.com/Linker
It seems to me like the #1 ILMerge Best Practice is Don't Use ILMerge. Instead, use SmartAssembly. One reason for this is that the #2 ILMerge Best Practice is to always run PEVerify after you do an ILMerge, because ILMerge does not guarantee it will correctly merge assemblies into a valid executable.
Other ILMerge disadvantages:
Another tool worth paying attention to is Mono.Cecil and the Mono.Linker [2] tool.
[2]: http:// www.mono-project.com/Linker
简介
这篇文章展示了如何用单个
组合.exe
替换所有.exe + .dll文件
。 它还可以保持调试.pdb
文件完好无损。对于控制台应用程序
以下是使用 .NET 4.0 的 Visual Studio 2010 SP1 的基本
后生成字符串
。 我正在构建一个控制台 .exe,其中包含所有子 .dll 文件。基本提示
AssemblyName.all.exe
”,它将所有子 dll 合并到一个 .exe 中。ILMerge\
目录。 您需要将 ILMerge 实用程序复制到解决方案目录中(这样您就可以分发源代码,而不必担心记录 ILMerge 的安装),或者更改此路径以指向 ILMerge.exe 所在的位置。高级提示
如果您遇到无法正常工作的问题,请打开
输出
,然后选择显示来自:构建的输出
。 检查 Visual Studio 实际生成的确切命令,并检查是否有错误。示例构建脚本
此脚本将所有
.exe + .dll 文件
替换为单个组合 .exe
。 它还可以保持调试 .pdb 文件完好无损。要使用,请将其粘贴到 C# 项目中的
Build Events
选项卡下的Post Build
步骤中,并确保将第一行中的路径调整为指向 <代码>ILMerge.exe:Introduction
This post shows how to replace all
.exe + .dll files
with a singlecombined .exe
. It also keeps the debugging.pdb
file intact.For Console Apps
Here is the basic
Post Build String
for Visual Studio 2010 SP1, using .NET 4.0. I am building a console .exe with all of the sub-.dll files included in it.Basic hints
AssemblyName.all.exe
" which combines all sub-dlls into one .exe.ILMerge\
directory. You need to either copy the ILMerge utility into your solution directory (so you can distribute the source without having to worry about documenting the install of ILMerge), or change the this path to point to where ILMerge.exe resides.Advanced hints
If you have problems with it not working, turn on
Output
, and selectShow output from: Build
. Check the exact command that Visual Studio actually generated, and check for errors.Sample Build Script
This script replaces all
.exe + .dll files
with a singlecombined .exe
. It also keeps the debugging .pdb file intact.To use, paste this into your
Post Build
step, under theBuild Events
tab in a C# project, and make sure you adjust the path in the first line to point toILMerge.exe
: