【发布时间】:2009-12-22 13:16:36
【问题描述】:
包含托管和非托管代码混合的 .NET 程序集不能与其他程序集进行 ILMerged。
如何验证给定的 .NET 程序集是包含纯托管代码,还是包含托管代码和非托管代码?
【问题讨论】:
标签: .net assemblies unmanaged native
包含托管和非托管代码混合的 .NET 程序集不能与其他程序集进行 ILMerged。
如何验证给定的 .NET 程序集是包含纯托管代码,还是包含托管代码和非托管代码?
【问题讨论】:
标签: .net assemblies unmanaged native
根据 nobugz 的建议,查看 CLR 标志的更简单方法是使用 corflags 实用程序,它是 .NET 2.0 SDK 的一部分。
如果没有指定选项,则显示给定图像的标志:
C:\>corflags Foo.dll
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 9
ILONLY : 1
32BIT : 0
Signed : 1
“ILONLY”位指示这是纯托管程序集还是混合程序集。
请注意,用户“nobugz”的评论表明这些标志不能保证是正确的,因此这种方法可能不是万无一失的。
【讨论】:
对您的程序集运行PEVerify 工具。
PEVerify.exe 与 Visual Studio 一起安装,例如这个是 Visual Studio 2012 自带的:
C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\PEVerify.exe
【讨论】:
从 Visual Studio 命令提示符运行 ildasm,如下所示:
ildasm file.exe /headers /noil /text
在输出结束时,您将看到以下内容:
// ----- CLR 标头:
// 标题大小:...
// 主要运行时版本:...
// 次要运行时版本:...
// ...
// 标志:0x00000000
如果 Flags 设置了最低位(例如 0x00000001),则程序集是纯 CLR;如果不是(例如 0x00000000),则程序集为混合模式。请注意,可能存在其他标志,因此它只是您感兴趣的最低位(因此,如果最后一位数字是 1、3、5、7、9、b、d 或 f,那么它就是纯 CLR)。
(编辑:您也可以以图形方式运行 ildasm,打开相关的可执行文件,然后从“查看”菜单中选择“标题”以查看相同的信息。)
【讨论】:
改进上面提供的答案 Wim...
找到你的“PEVerify.exe” - 如果你安装了 VS,你就拥有它。 - 将完整路径复制到 PEVerify.exe 文件,你的路径将不同 - - 这是一个示例:C:\Program文件 (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\PEVerify.exe
打开 Visual Studio 命令提示符(不要“以管理员身份运行”)
输入:cd C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools
您的命令提示符现在应该是这个长文本,而不仅仅是 C:\ 之类的......它将指向 PEVerify.exe 所在的路径。
现在输入:peverify "your full path to your dll you want to check - 然后按 Enter - 这是我的示例:peverify "G:\TestFolder\My_Managed_OR_Unmanaged.dll"
按 Enter 后,您会收到如下消息,它的 100% 托管 dll - My_Managed_OR_Unmanaged.dll 中的所有类和方法均已验证。”
【讨论】:
要从 C# 中获取 PE 标志,请使用 System.Reflection API:http://www.example8.com/category/view/id/6027
...
Assembly a = Assembly.GetExecutingAssembly();
Module m = a.ManifestModule;
PortableExecutableKinds peKinds;
ImageFileMachine imageFileMachine;
m.GetPEKind(out peKinds, out imageFileMachine);
if ((peKinds & PortableExecutableKinds.ILOnly) != 0)
...
【讨论】:
我必须仔细检查一下,但我很确定您可以通过 redgate 使用 Reflector 找到它。
【讨论】:
ILMerge 仅合并托管程序集,here,引用他们的下载页面,“ILMerge 是用于将多个 .NET 程序集合并为单个 .NET 程序集的实用程序”。
我还没有看到托管程序集与本机二进制文件合并。从技术上讲,您可以将它们本身合并,通过将非托管二进制文件包含为嵌入式资源,但是将嵌入式资源作为二进制代码加载到内存中 - 我以前从未见过这种情况。我已经尝试过使用内存映射的技术,但失败了。
另一种检查方法是查看二进制文件本身,如果它在数据目录中有第 15 个条目,并且不为零,那么它是一个 .NET 二进制文件,本机二进制文件没有这个。请参阅 here 我在其中发布了类似问题的答案。
希望这会有所帮助, 最好的祝福, 汤姆。
【讨论】:
我认为你应该使用 .NET 反射来遍历程序集中的所有类型和方法。
【讨论】: