.net ILMerge生成的程序集不';t运行,尽管日志输出没有报告错误-这是为什么?
我正在为一个新项目测试ILMerge,尽管.exe文件似乎创建正确,但它不会运行 我已经通过.msi安装程序(在这里找到)安装了ILMerge,并且正在使用批处理文件在测试项目上运行。下面是批处理文件,以及运行后的后续输出日志。日志中的所有显示正常,未报告任何错误。我正在为这个测试项目运行.NETFramework4.0 当我尝试运行.exe时,它失败了,出现了一个标准的“此程序已停止工作” 我读到一些人在运行.NET4时遇到问题,但我认为我已经添加了正确的参数来处理这个问题。无论是否添加.NET 4参数,我都会得到相同的结果 有人知道为什么会这样吗?提前谢谢 批处理文件.net ILMerge生成的程序集不';t运行,尽管日志输出没有报告错误-这是为什么?,.net,ilmerge,.net,Ilmerge,我正在为一个新项目测试ILMerge,尽管.exe文件似乎创建正确,但它不会运行 我已经通过.msi安装程序(在这里找到)安装了ILMerge,并且正在使用批处理文件在测试项目上运行。下面是批处理文件,以及运行后的后续输出日志。日志中的所有显示正常,未报告任何错误。我正在为这个测试项目运行.NETFramework4.0 当我尝试运行.exe时,它失败了,出现了一个标准的“此程序已停止工作” 我读到一些人在运行.NET4时遇到问题,但我认为我已经添加了正确的参数来处理这个问题。无论是否添加.NE
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版本2.11.1103.0
版权所有(C)微软公司2004-2006。版权所有。
ILMerge/lib:C:\Windows\Microsoft.NET\Framework\v4.0.30319/lib:C:\Program Files(x86)\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblys/t:exe/log:C:\WORKING\DIR\Testimerge\Testimerge\bin\Debug\Combinedll\MergeLog.txt/target:winexe/targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319/out:C:\WORKING\DIR\testimerge\testimerge\bin\Debug\CombinedDLL\CombinedDLL.exe C:\WORKING\DIR\testimerge\bin\Debug\testimerge.exe C:\WORKING\DIR\testimerge\TestDLL2\bin\Debug\TestDLL2.dll C:\WORKING\DIR\testimerge\TestDLL3\bin\Debug\TestDLL3.dll
使用mscorlib.dll的目录“C:\Windows\Microsoft.NET\Framework\v4.0.30319”,将平台设置为“v4”
在Microsoft(R).NET Framework v2.0.50727上运行
mscorlib.dll版本=2.0.0.0
输入程序集的列表为:
C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\TestILMerge.exe
C:\WORKING\DIR\testlmerge\TestDLL2\bin\Debug\TestDLL2.dll
C:\WORKING\DIR\TestILMerge\TestDLL3\bin\Debug\TestDLL3.dll
正在尝试从文件“C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\TestILMerge.exe”读取程序集。
已成功读入程序集。
TestILMerge的元数据中未报告任何错误。
正在尝试从文件“C:\WORKING\DIR\TestILMerge\TestDLL2\bin\Debug\TestDLL2.dll”读取程序集。
已成功读入程序集。
TestDLL2的元数据中未报告任何错误。
正在尝试从文件“C:\WORKING\DIR\TestILMerge\TestDLL3\bin\Debug\TestDLL3.dll”读取程序集。
已成功读入程序集。
TestDLL3的元数据中未报告任何错误。
检查所有输入程序集是否具有兼容的PeKind。
TestILMerge.PeKind=ILonly,需要32位
TestDLL2.PeKind=ILonly
TestDLL3.PeKind=ILonly
所有输入程序集都具有兼容的PeKind值。
对目标程序集的程序集级属性使用程序集“TestILMerge”。
正在将程序集“TestILMerge”合并到目标程序集。
正在将程序集“TestDLL2”合并到目标程序集。
正在将程序集“TestDLL3”合并到目标程序集。
正在将2个Win32资源从程序集“TestILMerge”复制到目标程序集。
正在将入口点“TestILMerge.Program.Main(System.String[])”从程序集“TestILMerge”传输到程序集“CombinedDLL”。
目标程序集的元数据中未报告任何错误。
ILMerge:正在写入目标程序集“C:\WORKING\DIR\TestILMerge\TestILMerge\bin\Debug\CombinedDLL\CombinedDLL.exe”。
引用的程序集“mscorlib”的位置是“C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll”
mscorlib的元数据中未报告任何错误。
伊尔梅:完成了。
更新:这是disassembly-看起来就像我期望的那样
解除装配
更新2
我发现,如果我引用另一个项目并将其用作程序集,而不是独立的可执行文件,则该组件可以工作。也许这不会解决您的问题,但我认为最好验证您的ilmerged可执行文件不包含对合并库的引用。你可以和ILSpy核实一下(http://wiki.sharpdevelop.net/ILSpy.ashx)-只需反汇编合并的可执行文件,并在树中检查引用中的程序集。ILSpy还可以帮助您验证ilmerged可执行文件是否包含来自合并程序集的类 下一个选项还可以是在尝试启动应用程序时调试程序集绑定(http://msdn.microsoft.com/en-us/library/e74a18c4%28v=VS.100%29.aspx). 您还可以尝试调试合并的程序集,以查明应用程序是否在调用主函数之前崩溃,或者可能在内部某个地方崩溃
我认为识别无法找到的特定类型可以帮助解决问题 检查事件查看器以查看任何详细的错误消息 将
void Main(字符串args[])
方法的主体用
try
{
...
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
例如,还可以尝试将平台目标更改为x86
如果指定了
/targetplatform:v4
则不需要在/lib
和/targetplatform
命令行开关上指定.net framework目录,如果编写了所有要合并的程序集,则ILMerge非常好,您知道,他们中没有人对装配组织进行假设。但是在许多情况下(特别是涉及重反射或动态语言运行时的情况),ILMerge根本不起作用。有时事情会以令人惊讶和神秘的方式失败
当ILMerge失败时,杰弗里·里克特(Jeffrey Richter)已经成功了
这不是没有取舍的,但即使是ILMerge的作者Mike Barnett在那篇博文的评论帖子中说,“作为ILMerge的作者,我认为这太棒了!如果我知道这一点,我永远不会写ILMerge。”
如果你能使用里希特的方法,你就不会被大多数反射或动态陷阱绊倒
var resourceStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(name);
return Assembly.Load(new BinaryReader(resourceStream).ReadBytes(int.MaxValue));
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);
}