如何使用 C# 判断一个文件是否为程序集

Posted dotNET跨平台

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用 C# 判断一个文件是否为程序集相关的知识,希望对你有一定的参考价值。

程序集是经由编译器编译得到的,供 CLR 进一步编译执行的那个中间产物。它一般表现为 .dll 或者是 .exe 的格式,但是要注意,它们跟普通意义上的 WIN32 可执行程序是完全不同的东西,程序集必须依靠 CLR 才能顺利执行。程序集是 .NET 编程的基本组成部分。

如何手动确认一个文件是否为程序集

  1. 启动 IL 反汇编程序(如 Ildasm.exe 或者 ILSpy)。

  2. 载入你想测试的文件。

  3. 如果可以正常载入显示了程序集信息,则说明为程序集。如果提示 “that the file is not a portable executable (PE) file” 则表示该文件不是程序集文件。

如何使用编程方式判断一个文件是否为程序集

使用 AssemblyName

  1. 调用 AssemblyName.GetAssemblyName 方法,传递测试文件的完整路径。

  2. 如果引发 BadImageFormatException 异常,则该文件不是程序集。

此示例测试 DLL 是否为程序集:

using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;


static class ExampleAssemblyName

    public static void CheckAssembly()
    
        try
        
            string path = Path.Combine(
                RuntimeEnvironment.GetRuntimeDirectory(),
                "System.Net.dll");


            AssemblyName testAssembly = AssemblyName.GetAssemblyName(path);
            Console.WriteLine("Yes, the file is an assembly.");
        
        catch (FileNotFoundException)
        
            Console.WriteLine("The file cannot be found.");
        
        catch (BadImageFormatException)
        
            Console.WriteLine("The file is not an assembly.");
        
        catch (FileLoadException)
        
            Console.WriteLine("The assembly has already been loaded.");
        
    


    /* Output:
    Yes, the file is an assembly.  
    */

GetAssemblyName 方法会先加载测试文件,然后在读取信息后释放。

使用 PEReader

  1. 安装 NuGet 包 :System.Reflection.Metadata

  2. 创建一个 System.IO.FileStream 实例,用于从测试文件读取数据。

  3. 创建一个 System.Reflection.PortableExecutable.PEReader 实例,并把文件流传递给构造函数。、

  4. 检查 HasMetadata 属性值。如果为 

    false

     ,则该文件不是程序集。

  5. 调用 PEReader 实例的 GetMetadataReader 方法,创建一个元数据读取器。

  6. 检查 IsAssembly 属性值。如果为 

    false

     ,则该文件不是程序集。

与 GetAssemblyName 方法不同,PEReader 不会在本机可移植可执行文件(PE)上引发异常。这使您能够在需要检查此类文件时避免异常导致的额外性能成本。如果文件不存在或不是PE文件,您仍然需要处理异常。

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Runtime.InteropServices;


static class ExamplePeReader

    static bool IsAssembly(string path)
    
        using var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);


        // Try to read CLI metadata from the PE file.
        using var peReader = new PEReader(fs);


        if (!peReader.HasMetadata)
        
            return false; // File does not have CLI metadata.
        


        // Check that file has an assembly manifest.
        MetadataReader reader = peReader.GetMetadataReader();
        return reader.IsAssembly;
    


    public static void CheckAssembly()
    
        string path = Path.Combine(
                RuntimeEnvironment.GetRuntimeDirectory(),
                "System.Net.dll");


        try
        
            if (IsAssembly(path))
            
                Console.WriteLine("Yes, the file is an assembly.");
            
            else
            
                Console.WriteLine("The file is not an assembly.");
            
        
        catch (BadImageFormatException)
        
            Console.WriteLine("The file is not an executable.");
        
        catch (FileNotFoundException)
        
            Console.WriteLine("The file cannot be found.");
        
    


    /* Output:
    Yes, the file is an assembly.  
    */

以上是关于如何使用 C# 判断一个文件是否为程序集的主要内容,如果未能解决你的问题,请参考以下文章

C#动态加载dll 时程序集的卸载问题

如何将附属程序集嵌入到 EXE 文件中

编写一个C#控制台应用程序,从键盘输入年份,判断此年份是否闰年。

C#中的命名空间和程序集

C#中的命名空间和程序集

C#调用了一个DLL文件,如何查看DLL的使用方法?小白求问