C# ILMerge 最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9376/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
ILMerge Best Practices
提问by James Pogran
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?
你使用 ILMerge 吗?您是否使用 ILMerge 合并多个程序集以简化 dll 的部署?在将 ILMerging 程序集放在一起后,您是否在生产中发现部署/版本控制问题?
I'm looking for some advice in regards to using ILMerge to reduce deployment friction, if that is even possible.
如果可能的话,我正在寻找有关使用 ILMerge 减少部署摩擦的一些建议。
采纳答案by Lamar
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.
我几乎所有不同的应用程序都使用 ILMerge。我将它直接集成到发布构建过程中,所以我最终得到的是每个应用程序一个 exe,没有额外的 dll。
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.
您不能 ILMerge 任何具有本机代码的 C++ 程序集。您也不能 ILMerge 任何包含 WPF XAML 的程序集(至少我没有成功)。它在运行时抱怨无法找到资源。
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.
我确实为 ILMerge 编写了一个包装器可执行文件,我在其中传递了要合并的项目的启动 exe 名称和输出 exe 名称,然后它反映了依赖程序集并使用适当的命令行参数调用 ILMerge。现在当我向项目添加新程序集时要容易得多,我不必记得更新构建脚本。
回答by Esteban Araya
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.
我们在很多项目中使用 ILMerge。例如,Web 服务软件工厂产生 8 个程序集作为其输出。我们将所有这些 DLL 合并到一个 DLL 中,这样服务主机只需引用一个 DLL。
It makes life somewhat easier, but it's not a big deal either.
它使生活更轻松一些,但这也没什么大不了的。
回答by Surgical Coder
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.
我们在 Microsoft 应用程序块上使用 ILMerge - 而不是 12 个单独的 DLL 文件,我们有一个可以上传到我们客户区的文件,而且文件系统结构更整洁。
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.
合并文件后,我必须编辑visual studio项目列表,删除12个单独的程序集并添加单个文件作为参考,否则它会抱怨找不到特定程序集。我不太确定这在部署后如何工作,值得一试。
回答by markom
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.
我们刚刚开始在我们的解决方案中使用 ILMerge,这些解决方案在我们的其他项目中重新分发和使用,到目前为止效果很好。一切似乎都正常。我们甚至直接混淆了打包的程序集。
We are considering doing the same with the MS Enterprise Library assemblies.
我们正在考虑对 MS Enterprise Library 程序集做同样的事情。
The only real issue I see with it is versioning of individual assemblies from the package.
我看到的唯一真正问题是包中单个程序集的版本控制。
回答by Patrick
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.
在合并具有相同命名空间中的资源的 DLL 时,我们遇到了问题。在合并过程中,资源命名空间之一被重命名,因此无法定位资源。也许我们只是在那里做错了什么,仍在调查这个问题。
回答by Ismail
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.
我最近遇到了问题,我在程序集中合并了程序集,我有一些类是通过 Umbraco 开源 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?
通过反射进行调用的信息取自具有程序集名称和实现的类的命名空间和接口的 db 表。问题是当 dll 被合并时反射调用会失败,但是如果 dll 是单独的,它一切正常。我认为问题可能类似于 longeasy 所拥有的问题?
回答by user429921
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.
在我看来,#1 ILMerge 最佳实践是不要使用 ILMerge。相反,使用SmartAssembly。原因之一是 #2 ILMerge 最佳实践是在执行 ILMerge 后始终运行 PEVerify,因为 ILMerge 不保证它会正确地将程序集合并到有效的可执行文件中。
Other ILMerge disadvantages:
其他 ILMerge 缺点:
- when merging, it strips XML Comments (if I cared about this, I would use an obfuscation tool)
- it doesn't correctly handle creating a corresponding .pdb file
- 合并时,它会去除 XML 注释(如果我关心这个,我会使用混淆工具)
- 它不能正确处理创建相应的 .pdb 文件
Another tool worth paying attention to is Mono.Cecil and the Mono.Linker [2] tool.
另一个值得关注的工具是 Mono.Cecil 和 Mono.Linker [2] 工具。
[2]: http:// www.mono-project.com/Linker
[2]:http://www.mono-project.com/Linker
回答by Contango
Introduction
介绍
This post shows how to replace all .exe + .dll files
with a single combined .exe
. It also keeps the debugging .pdb
file intact.
这篇文章展示了如何.exe + .dll files
用单个combined .exe
. 它还可以保持调试.pdb
文件完好无损。
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.
这是Post Build String
使用 .NET 4.0 的 Visual Studio 2010 SP1的基础。我正在构建一个包含所有子 .dll 文件的控制台 .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
Basic hints
基本提示
- The output is a file "
AssemblyName.all.exe
" which combines all sub-dlls into one .exe. - Notice the
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.
- 输出是一个文件“
AssemblyName.all.exe
”,它将所有子 dll 组合成一个 .exe。 - 注意
ILMerge\
目录。您需要将 ILMerge 实用程序复制到您的解决方案目录中(这样您就可以分发源代码而不必担心记录 ILMerge 的安装),或者更改此路径以指向 ILMerge.exe 所在的位置。
Advanced hints
高级提示
If you have problems with it not working, turn on Output
, and select Show output from: Build
. Check the exact command that Visual Studio actually generated, and check for errors.
如果您遇到无法正常工作的问题,请打开Output
,然后选择Show output from: Build
。检查 Visual Studio 实际生成的确切命令,并检查错误。
Sample Build Script
示例构建脚本
This script replaces all .exe + .dll files
with a single combined .exe
. It also keeps the debugging .pdb file intact.
此脚本将所有内容替换.exe + .dll files
为单个combined .exe
. 它还可以保持调试 .pdb 文件完好无损。
To use, paste this into your Post Build
step, under the Build Events
tab in a C# project, and make sure you adjust the path in the first line to point to ILMerge.exe
:
要使用,请将其粘贴到您的Post Build
步骤中,在Build Events
C# 项目的选项卡下,并确保将第一行中的路径调整为指向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
回答by Mightymuke
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 来减少依赖项的数量,而且还将实用程序使用的“内部”依赖项(例如 automapper、restsharp 等)内化。这意味着它们被完全抽象掉了,使用合并实用程序的项目不需要知道它们。这再次减少了项目中所需的引用,并允许它在需要时使用/更新同一外部库的自己版本。
回答by rexall
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.
我们在组合 WPF 依赖项时遇到了同样的问题...... ILMerge 似乎没有处理这些问题。然而,Costura.Fody 对我们来说效果很好,花了大约 5 分钟才开始……非常好的体验。
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.
只需使用 Nuget 安装(在包管理器控制台中选择正确的默认项目)。它将自己引入目标项目,默认设置立即对我们有用。
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).
它合并所有标记为“Copy Local” = true 的 DLL,并生成一个合并的 .EXE(与标准输出一起),其大小被很好地压缩(远小于总输出大小)。
The license is MIT as so you can modify/distribute as required.
许可证是 MIT,因此您可以根据需要修改/分发。