简体   繁体   English

检查文件是否是.NET程序集

[英]Checking if a file is a .NET assembly

I've seen some methods of checking if a PEFile is a .NET assembly by examining the binary structure . 通过检查二进制结构,我已经看到了一些检查PEFile是否是.NET程序集的方法

Is that the fastest method to test multiple files? 这是测试多个文件的最快方法吗? I assume that trying to load each file (eg via Assembly.ReflectionOnlyLoad ) file might be pretty slow since it'll be loading file type information. 我假设尝试加载每个文件(例如通过Assembly.ReflectionOnlyLoad )文件可能会很慢,因为它将加载文件类型信息。

Note: I'm looking for a way to check files programmatically. 注意:我正在寻找一种以编程方式检查文件的方法。

I guess Stormenet's answer isn't technically programmatic , so I'll seperate my response into an answer. 我猜Stormenet的答案在技术上并不是程序化的 ,所以我会将我的回答分成一个答案。

For best performance, nothing is going to beat opening the file(s) with a StreamReader , reading the first (n) bytes and checking for the .NET file signature data structures in the byte stream. 为了获得最佳性能,没有什么比使用StreamReader打开文件更好,读取第一个(n)字节并检查字节流中的.NET文件签名数据结构。

Pretty much the same way you'd verify something is a DOS executable: 几乎与验证某些东西是DOS可执行文件的方式相同:

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

Look for the "MZ" header bytes, which also happen to be the initials of Mark Zbikowski, one of the developers of MS-DOS.. 寻找“MZ”头字节,这也恰好是MS-DOS开发人员之一Mark Zbikowski的缩写。

Maybe this helps 也许这有帮助

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

Next, I check to see if it is a .NET assembly. 接下来,我检查它是否是.NET程序集。 To do this I check to see if the file contains the CLR header. 为此,我检查文件是否包含CLR标头。 This header contains important information about the location of the .NET code in the file and the version of the framework that was used to write that code. 此标头包含有关.NET代码在文件中的位置以及用于编写该代码的框架版本的重要信息。 The location of this header is given in the file's Data Directory table. 此标头的位置在文件的数据目录表中给出。 If the data directory item has zero values then the file is unmanaged, if it has non-zero values then the file is a .NET assembly. 如果数据目录项的值为零,则文件是非托管的,如果它具有非零值,则该文件是.NET程序集。

You can test this yourself using the dumpbin utility with the /headers switch. 您可以使用带有/ headers开关的dumpbin实用程序自行测试。 This utility will print the various headers in a file on the command line. 此实用程序将在命令行上的文件中打印各种标头。 At the end of the Optional Header Values you'll see a list of the Data Directories (there will always be 16 of them) and if the COM Descriptor Directory has a non-zero location it indicates that the file is a .NET assembly. 在可选标题值的末尾,您将看到数据目录的列表(其中将始终有16个),如果COM描述符目录具有非零位置,则表示该文件是.NET程序集。 The contents of the CLR header can also be listed using the /clrheader switch (if the file is unmanaged this will show no values). 还可以使用/ clrheader开关列出CLR标头的内容(如果文件未受管理,则不显示任何值)。 XP tests for the CLR header when it executes a file and if the CLR header is present it will initialize the runtime and pass the entry point of the assembly to the runtime, so that the file runs totally within the runtime. XP在执行文件时测试CLR头,如果存在CLR头,它将初始化运行时并将程序集的入口点传递给运行时,以便文件在运行时内完全运行。

In the past I've used AssemblyName.GetAssemblyName(), which throws an exception if it's not a managed assembly. 在过去,我使用了AssemblyName.GetAssemblyName(),如果它不是托管程序集,则抛出异常。 However, I've never performance tested it, so I can't say how fast it is. 但是,我从来没有对它进行性能测试,所以我不能说它有多快。

Official Documentation 官方文件

The first link there is going to be the fastest and simplest method of checking (the PE file header one). 第一个链接将是最快速和最简单的检查方法(PE文件头一个)。 You're correct in assuming that calling Assembly.ReflectionOnlyLoad is going to be pretty slow. 假设调用Assembly.ReflectionOnlyLoad会非常慢,你是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM