Share via


Anvisningar: Avgöra om en fil är en sammansättning

En fil är en sammansättning om och endast om den hanteras och innehåller en sammansättningspost i dess metadata. Mer information om sammansättningar och metadata finns i Sammansättningsmanifest.

Så här avgör du manuellt om en fil är en sammansättning

  1. Starta verktyget Ildasm.exe (IL Disassembler).

  2. Läs in filen som du vill testa.

  3. Om ILDASM rapporterar att filen inte är en bärbar körbar fil (PE) är det inte en sammansättning. Mer information finns i avsnittet Så här: Visa sammansättningsinnehåll.

Så här avgör du programmatiskt om en fil är en sammansättning

Använda klassen AssemblyName

  1. AssemblyName.GetAssemblyName Anropa metoden och skicka den fullständiga filsökvägen och namnet på filen som du testar.

  2. Om ett BadImageFormatException undantag utlöses är filen inte en sammansättning.

I det här exemplet testas en DLL för att se om det är en sammansättning.

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.  

Metoden GetAssemblyName läser in testfilen och släpper den sedan när informationen har lästs.

Använda KLASSEN PEReader

  1. Om du riktar in dig på .NET Standard eller .NET Framework installerar du NuGet-paketet System.Reflection.Metadata . (När du riktar in dig på .NET Core eller .NET 5+ krävs inte det här steget eftersom det här biblioteket ingår i det delade ramverket.)

  2. Skapa en System.IO.FileStream instans för att läsa data från filen som du testar.

  3. Skapa en System.Reflection.PortableExecutable.PEReader instans och skicka filströmmen till konstruktorn.

  4. Kontrollera värdet för HasMetadata egenskapen. Om värdet är falseär filen inte en sammansättning.

  5. GetMetadataReader Anropa metoden på PE-läsarinstansen för att skapa en metadataläsare.

  6. Kontrollera värdet för IsAssembly egenskapen. Om värdet är trueär filen en sammansättning.

GetAssemblyName Till skillnad från metoden PEReader genererar klassen inte ett undantag på interna PE-filer (Portable Executable). På så sätt kan du undvika den extra prestandakostnaden som orsakas av undantag när du behöver kontrollera sådana filer. Du måste fortfarande hantera undantag om filen inte finns eller inte är en PE-fil.

Det här exemplet visar hur du avgör om en fil är en sammansättning med hjälp av PEReader klassen.

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.

Se även