.net - 尽管日志输出没有报告错误,但 ILMerge 生成的程序集无法运行 - 这是为什么?

标签 .net ilmerge

我正在为一个新项目测试 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.

更新:这是反汇编 - 看起来正如我所期望的

反汇编

enter image description here

更新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。”

如果您可以使用里希特方​​法,您就不会陷入大多数反射或动态陷阱。

实现步骤

  1. 将您依赖的所有第三方程序集嵌入到应用程序的资源中。
  2. 注册 ResolveEventHandler使用 AppDomain.CurrentDomain.AssemblyResolve 事件。
  3. 当使用您存储在资源中的程序集调用您的处理程序时,加载该程序集。

您按如下方式执行第 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/

相关文章:

c# - C# 中的非标准 UI

c# - 嵌套在类中的扩展方法

c# - 使用 ILMerge 合并 .dll 文件失败

c# - 如何在安装项目中使用 IlMerge?

c# - 将 ILMerge 与 IronPython 结合使用

.net - ILMerge 程序集的运行时版本是 v4.0.20926;预期版本是 v4.0.30319

c# - 如何将 TreeView 中的 SelectedItemValue 绑定(bind)回 Silverlight 中的 ViewModel?

.net - HttpWebRequest - POST 中不允许使用括号

c# - 使用 ExpertPDF 从 HTML 生成的 PDF 的质量差异

c# - 使用 ILMerge 后应用程序停止记录