12

我已经看到了一些通过检查二进制结构来检查 PEFile 是否为 .NET 程序集的方法

这是测试多个文件的最快方法吗?我假设尝试加载每个文件(例如通过Assembly.ReflectionOnlyLoad)文件可能会很慢,因为它将加载文件类型信息。

注意:我正在寻找一种以编程方式检查文件的方法。

4

4 回答 4

7

我猜 Stormenet 的回答在技术上不是程序化的,所以我将把我的回答分成一个答案。

为了获得最佳性能,没有什么比使用 a 打开文件StreamReader、读取前 (n) 个字节并检查字节流中的 .NET 文件签名数据结构更好的了。

几乎与您验证某个 DOS 可执行文件的方式相同:

http://en.wikipedia.org/wiki/DOS_executable

寻找“MZ”标头字节,这也恰好是 MS-DOS 的开发者之一 Mark Zbikowski 的首字母。

于 2008-12-01T18:04:51.580 回答
6

也许这有帮助

来自https://web.archive.org/web/20110930194955/http://www.grimes.demon.co.uk/dotnet/vistaAndDotnet.htm

接下来,我检查它是否是一个 .NET 程序集。为此,我检查文件是否包含 CLR 标头。此标头包含有关 .NET 代码在文件中的位置以及用于编写该代码的框架版本的重要信息。此标头的位置在文件的数据目录表中给出。如果数据目录项的值为零,则该文件是非托管的,如果它具有非零值,则该文件是一个 .NET 程序集。

您可以使用带有 /headers 开关的 dumpbin 实用程序自行测试。该实用程序将在命令行上的文件中打印各种标题。在可选标头值的末尾,您将看到数据目录的列表(总是有 16 个),如果 COM 描述符目录的位置不为零,则表明该文件是一个 .NET 程序集。还可以使用 /clrheader 开关列出 CLR 标头的内容(如果文件是非托管的,则不会显示任何值)。XP 在执行文件时测试 CLR 标头,如果存在 CLR 标头,它将初始化运行时并将程序集的入口点传递给运行时,以便文件完全在运行时内运行。

于 2008-12-01T15:38:59.113 回答
6

过去我使用过 AssemblyName.GetAssemblyName(),如果它不是托管程序集,则会引发异常。但是,我从来没有对它进行性能测试,所以我不能说它有多快。

官方文档

于 2008-12-01T17:32:22.067 回答
1

第一个链接将是最快和最简单的检查方法(PE 文件头)。您假设调用 Assembly.ReflectionOnlyLoad 会很慢是正确的。

于 2008-12-01T04:57:13.603 回答