共用方式為


如何:判斷檔案是否為組裝

一個檔案當且僅當它被管理,且其元資料中包含一個組合體條目時,才是組裝檔。 欲了解更多關於組裝與元資料的資訊,請參閱 組裝清單

如何手動判斷一個檔案是否為組裝

  1. 啟動 Ildasm.exe(IL 反組譯器) 工具。

  2. 載入你想測試的檔案。

  3. ILDASM 報告該檔案不是可攜式執行檔(PE),則該檔案不屬於組合檔。 欲了解更多資訊,請參閱 主題「如何:查看組裝內容」。

如何程式化判斷一個檔案是否為組合語言

使用 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.  
    */
}
Imports System
Imports System.IO
Imports System.Reflection
Imports System.Runtime.InteropServices

Module ExampleAssemblyName
    Sub CheckAssembly()
        Try
            Dim filePath As String = Path.Combine(
                RuntimeEnvironment.GetRuntimeDirectory(),
                "System.Net.dll")

            Dim testAssembly As AssemblyName =
                                AssemblyName.GetAssemblyName(filePath)
            Console.WriteLine("Yes, the file is an Assembly.")
        Catch ex As FileNotFoundException
            Console.WriteLine("The file cannot be found.")
        Catch ex As BadImageFormatException
            Console.WriteLine("The file is not an Assembly.")
        Catch ex As FileLoadException
            Console.WriteLine("The Assembly has already been loaded.")
        End Try
    End Sub
End Module
' Output:  
' Yes, the file is an Assembly.  

GetAssemblyName 方法載入測試檔案,並在讀取資訊後釋放測試檔。

使用 PEReader 類別

謹慎

PEReaderSystem.Reflection.Metadata 程式庫並未設計用於處理不受信任的輸入。 格式錯誤或惡意的 PE 檔案可能導致意外行為,包括記憶體存取超出範圍、當機或凍結。 只使用這些 API 搭配受信任的組件。

  1. 如果你目標是 .NET Standard 或 .NET Framework,請安裝 System.Reflection.Metadata NuGet 套件。 (針對 .NET Core 或 .NET 5+,此步驟不需,因為此函式庫已包含於共享框架中。)

  2. 建立 System.IO.FileStream 一個實例來讀取你正在測試的檔案資料。

  3. 建立一個 System.Reflection.PortableExecutable.PEReader 實例,將你的檔案串流傳入建構子。

  4. 檢查HasMetadata屬性的值。 若值為 false,該檔案就不是組裝。

  5. 在 PE 讀取器實例中呼叫該 GetMetadataReader 方法來建立一個元資料讀取器。

  6. 檢查IsAssembly屬性的值。 若值為 true,則該檔案為組裝檔。

與該 GetAssemblyName 方法不同,該 PEReader 類別不會對原生可攜式可執行檔(PE)檔案拋出例外。 這能避免因異常狀況而產生的額外效能損失,尤其當你需要檢查這些檔案時。 你仍然需要處理例外,以防該檔案不存在或不是 PE 檔案。

這個範例展示了如何利用 類別 PEReader 判斷一個檔案是否為組合語言。

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.  
    */
}
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Reflection.Metadata
Imports System.Reflection.PortableExecutable
Imports System.Runtime.InteropServices

Module ExamplePeReader
    Function IsAssembly(path As String) As Boolean

        Dim fs As FileStream = New FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)

        ' Try to read CLI metadata from the PE file.
        Dim peReader As PEReader = New PEReader(fs)
        Using (peReader)
            If Not peReader.HasMetadata Then
                Return False ' File does Not have CLI metadata.
            End If

            ' Check that file has an assembly manifest.
            Dim reader As MetadataReader = peReader.GetMetadataReader()
            Return reader.IsAssembly
        End Using
    End Function

    Sub CheckAssembly()
        Dim filePath As String = Path.Combine(
                RuntimeEnvironment.GetRuntimeDirectory(),
                "System.Net.dll")

        Try
            If IsAssembly(filePath) Then
                Console.WriteLine("Yes, the file is an assembly.")
            Else
                Console.WriteLine("The file is not an assembly.")
            End If
        Catch ex As BadImageFormatException
            Console.WriteLine("The file is not an executable.")
        Catch ex As FileNotFoundException
            Console.WriteLine("The file cannot be found.")
        End Try
    End Sub
End Module
' Output:  
' Yes, the file is an Assembly.

另請參閱