我正在为一个新项目测试 ILMerge,尽管 .exe 文件似乎已正确创建,但它无法运行。
我已通过 .msi 安装程序(在此处 http://www.microsoft.com/download/en/confirmation.aspx?id=17630 找到)安装了 ILMerge,并使用批处理文件在测试项目上运行。下面是批处理文件,以及运行后的后续输出日志。日志中一切正常,没有报告错误。我正在为这个测试项目运行 .NET Framework 4.0。
当我尝试运行 .exe 时,它失败并显示标准“此程序已停止工作”。
我读到有些人在运行 .NET 4 时遇到问题,但我认为我已经添加了正确的参数来处理这个问题。无论是否添加 .NET 4 参数,我都会得到相同的结果。
谁能明白为什么会这样吗?提前致谢。
批处理文件
REM Clear directory first
CD C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL
DEL . /s/q
REM Change dir to iLMerge install (installed via msi installer)
REM Installer Download: http://www.microsoft.com/download/en/confirmation.aspx?id=17630
CD C:\Program Files (x86)\Microsoft\ILMerge\
REM Combine assemblies with logging
ilmerge.exe /lib:"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /lib:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies" /t:exe /log:C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL\MergeLog.txt /target:winexe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /out:C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL\CombinedDLL.exe C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\TestILMerge.exe C:\WORKING\DIR\TestILMerge\TestDLL2\bin\Debug\TestDLL2.dll C:\WORKING\DIR\TestILMerge\TestDLL3\bin\Debug\TestDLL3.dll
日志输出:
ILMerge version 2.11.1103.0
Copyright (C) Microsoft Corporation 2004-2006. All rights reserved.
ILMerge /lib:C:\Windows\Microsoft.NET\Framework\v4.0.30319 /lib:C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies /t:exe /log:C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL\MergeLog.txt /target:winexe /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /out:C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL\CombinedDLL.exe C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\TestILMerge.exe C:\WORKING\DIR\TestILMerge\TestDLL2\bin\Debug\TestDLL2.dll C:\WORKING\DIR\TestILMerge\TestDLL3\bin\Debug\TestDLL3.dll
Set platform to 'v4', using directory 'C:\Windows\Microsoft.NET\Framework\v4.0.30319' for mscorlib.dll
Running on Microsoft (R) .NET Framework v2.0.50727
mscorlib.dll version = 2.0.0.0
The list of input assemblies is:
C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\TestILMerge.exe
C:\WORKING\DIR\TestILMerge\TestDLL2\bin\Debug\TestDLL2.dll
C:\WORKING\DIR\TestILMerge\TestDLL3\bin\Debug\TestDLL3.dll
Trying to read assembly from the file 'C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\TestILMerge.exe'.
Successfully read in assembly.
There were no errors reported in TestILMerge's metadata.
Trying to read assembly from the file 'C:\WORKING\DIR\TestILMerge\TestDLL2\bin\Debug\TestDLL2.dll'.
Successfully read in assembly.
There were no errors reported in TestDLL2's metadata.
Trying to read assembly from the file 'C:\WORKING\DIR\TestILMerge\TestDLL3\bin\Debug\TestDLL3.dll'.
Successfully read in assembly.
There were no errors reported in TestDLL3's metadata.
Checking to see that all of the input assemblies have a compatible PeKind.
TestILMerge.PeKind = ILonly, Requires32bits
TestDLL2.PeKind = ILonly
TestDLL3.PeKind = ILonly
All input assemblies have a compatible PeKind value.
Using assembly 'TestILMerge' for assembly-level attributes for the target assembly.
Merging assembly 'TestILMerge' into target assembly.
Merging assembly 'TestDLL2' into target assembly.
Merging assembly 'TestDLL3' into target assembly.
Copying 2 Win32 Resources from assembly 'TestILMerge' into target assembly.
Transferring entry point 'TestILMerge.Program.Main(System.String[])' from assembly 'TestILMerge' to assembly 'CombinedDLL'.
There were no errors reported in the target assembly's metadata.
ILMerge: Writing target assembly 'C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL\CombinedDLL.exe'.
Location for referenced assembly 'mscorlib' is 'C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll'
There were no errors reported in mscorlib's metadata.
ILMerge: Done.
更新:这是反汇编 - 看起来正如我所期望的
反汇编
更新2
我发现,如果我从另一个项目引用并用作程序集,但不是独立的可执行文件,则该组件可以工作。
最佳答案
如果您编写了要合并的所有程序集,并且您知道它们都没有对程序集组织做出假设,那么 ILMerge 会非常有用。但在许多情况下(特别是涉及大量反射或动态语言运行时的情况),ILMerge 不起作用。有时事情会以令人惊讶和神秘的方式失败。
当 ILMerge 失败时,Jeffrey Richter 有 a more reliable way to get applications with multiple DLL dependencies to be deployable as a single assembly .
这并非没有权衡,但即使是 ILMerge 作者 Mike Barnett 也在该博文的评论中表示“作为 ILMerge 的作者,我认为这太棒了!如果我知道这一点,我永远不会写 ILMerge。”
如果您可以使用里希特方法,您就不会陷入大多数反射或动态陷阱。
实现步骤
- 将您依赖的所有第三方程序集嵌入到应用程序的资源中。
- 注册
ResolveEventHandler
使用AppDomain.CurrentDomain.AssemblyResolve
事件。 - 当使用您存储在资源中的程序集调用您的处理程序时,加载该程序集。
您按如下方式执行第 3 部分:
var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
return Assembly.Load(new BinaryReader(resourceStream).ReadBytes(int.MaxValue));
关于.net - 尽管日志输出没有报告错误,但 ILMerge 生成的程序集无法运行 - 这是为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8158757/