问题描述
我测试了ILMerge了一个新的项目,虽然该.exe文件似乎是正确创建,它不会运行。
I'm testing out ILMerge for a new project, and although the .exe file seems to be created correctly, it won't run.
我已经通过了.msi安装(此处http://www.microsoft.com/download/en/confirmation.aspx?id=17630)和我使用一个批处理文件测试项目在运行。下面是批处理文件,运行后出现的后续输出日志。所有出现确定在日志中,没有报告的错误。我在运行.NET Framework 4.0的这个测试项目。
I have installed ILMerge via the .msi installer (found here http://www.microsoft.com/download/en/confirmation.aspx?id=17630) and am running on a test project using a batch file. Below is the batch file, and the subsequent output log after running. All appears ok in the logs, no errors reported. I am running .NET framework 4.0 for this test project.
当我尝试运行.exe文件时,出现一个标准的此程序已停止工作。
When I try to run the .exe, it fails with a standard "This program has stopped working".
我看过,有些人有.NET 4上运行的问题,但我想我已经在正确的参数添加到处理这个问题。我得到了同样的结果,我是否添加了.NET 4的args与否。
I have read that some people have issues running with .NET 4, but I think I've added in the correct arguments to handle this. I get the same result whether I add in the .NET 4 args or not.
任何人都可以明白为什么这可能是?先谢谢了。
Can anyone see why this may be? Thanks in advance.
批处理文件
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.
更新:这里是dissassembly - 看起来,我希望它
UPDATE: Here is the dissassembly - looks as I would expect it to
Dissassembly
更新2
我发现,部分作品,如果我从另一个项目引用,并作为组件使用,而不是一个独立的可执行文件。
I have found that the component works if I reference from another project and use as an assembly, but not a standalone executable.
推荐答案
ILMerge是伟大的,如果你写的所有,你试图合并组件,你知道,他们都不是作出有关装配组织的假设。但是,在很多情况下(尤其是那些重的地方反射或动态语言运行时参与),ILMerge是行不通的。在令人惊讶和神秘的方式有时事情的失败。
ILMerge is great if you wrote all of the assemblies that you're trying to merge, and you know that none of them are making assumptions about assembly organization. But under many circumstances (especially ones where heavy reflection or the Dynamic Language Runtime are involved), ILMerge just doesn't work. Sometimes things fail in surprising and mysterious ways.
在ILMerge失败,杰弗里里希特有<一个href="http://blogs.msdn.com/b/microsoft_$p$pss/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx"相对=nofollow>一个更可靠的方式来获得与多个DLL依赖的应用程序是部署作为一个部件。
When ILMerge fails, Jeffrey Richter has a more reliable way to get applications with multiple DLL dependencies to be deployable as a single assembly.
这不是没有取舍,但即使是ILMerge作者,迈克·巴尼特,在上一篇博客文章作为ILMerge的作者的评论跟帖说,我认为这是太棒了!如果我早知道这一点,我永远都不会写ILMerge。
It isn't without trade-offs, but even the ILMerge author, Mike Barnett, said in the comment thread on that blog post "As the author of ILMerge, I think this is fantastic! If I had known about this, I never would have written ILMerge."
如果你可以使用里希特的方法,你会不会绊倒最该反思和活力的陷阱。
If you can use Richter's method, you won't trip over most of the reflection or dynamism traps.
的实施步骤
- 在嵌入所有你依赖于应用程序的资源的第三方组件。
- 注册一个<一个href="http://blogs.msdn.com/b/microsoft_$p$pss/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx"相对=nofollow>
ResolveEventHandler
与AppDomain.CurrentDomain.AssemblyResolve
事件。 - 当你的处理程序被调用时,你在藏资源的组件,加载程序集。
- Embed all of the third-party assemblies that you depend on in your application's Resources.
- Register a
ResolveEventHandler
with theAppDomain.CurrentDomain.AssemblyResolve
event. - When your handler gets called with an assembly that you stashed in Resources, load the assembly.
您做的第3部分如下:
var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
return Assembly.Load(new BinaryReader(resourceStream).ReadBytes(int.MaxValue));
这篇关于ILMerge生成的程序集不运行,虽然日志的输出没有报告任何错误 - 这是为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!