我正在测试ILMerge的新项目,虽然.exe文件似乎是正确创建的,但它不会运行.
我已经通过.msi安装程序(在http://www.microsoft.com/download/en/confirmation.aspx?id=17630中找到)安装了ILMerge,并且正在使用批处理文件运行测试项目.下面是批处理文件,以及运行后的后续输出日志.所有日志中都显示正常,未报告错误.我正在为这个测试项目运行.NET framework 4.0.
当我尝试运行.exe时,它失败并带有标准的"此程序已停止工作".
我已经读过有些人在使用.NET 4时遇到了问题,但我认为我已经添加了正确的参数来处理这个问题.无论我是否添加.NET 4 args,我都得到相同的结果.
任何人都可以看到为什么这可能是?提前致谢.
批处理文件
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
Run Code Online (Sandbox Code Playgroud)
日志输出:
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.
Run Code Online (Sandbox Code Playgroud)
更新:这是反汇编 - 看起来像我期望的那样
Dissassembly

更新2
我发现如果我从另一个项目引用并作为程序集使用该组件,但不是独立的可执行文件.
ILMerge非常棒,如果您编写了所有要合并的程序集,并且您知道它们都没有对程序集组织做出假设.但在许多情况下(尤其是涉及重度反射或动态语言运行时的情况),ILMerge只是不起作用.有时事情以令人惊讶和神秘的方式失败.
当ILMerge失败时,Jeffrey Richter有一种更可靠的方法来将具有多个DLL依赖关系的应用程序部署为单个程序集.
这不是没有权衡,但即使是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));
Run Code Online (Sandbox Code Playgroud)
小智 5
可以在 Visual Studio 2010 中轻松创建完全独立的可执行文件,并且此方法根本不需要 ILMerge。
脚步:
在此之后,Visual Studio 将自动创建一个名为 Resources 的新类,您必须在新项目中使用它。
然后你必须用 Visual Studio 编译你的程序,就是这样。
static void Main(string[] args)
{
// Load your assembly with the entry point from resources:
Assembly start = Assembly.Load((byte[]) Properties.Resources.NameOfDllOrExeInYourResources);
Type t = start.GetType("Foo.Bar.Program");
// Install the resolver event
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
// Find Program.Main in the loaded assembly
MethodInfo m = t.GetMethod("Main", BindingFlags.Public | BindingFlags.Static);
// Launch the application
m.Invoke(null, new object[] { args });
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
string assemblyName = new AssemblyName(args.Name).Name.Replace('.', '_');
// Locate and load the contents of the resource
byte[] assemblyBytes = (byte[]) Properties.Resources.ResourceManager.GetObject(assemblyName, Properties.Resources.Culture);
// Return the loaded assembly
return Assembly.Load(assemblyBytes);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9860 次 |
| 最近记录: |