How to check if a DLL and an exe is a .NET assembly

 
 
  • Gérald Barré

Recently, I needed to check whether a file was a .NET assembly without loading it. .NET uses the Portable Executable (PE) format to store assemblies. The PE format is used for executables and DLLs on Windows, but .NET also relies on it on Linux and macOS. Fortunately, .NET provides the PEReader class to read the file header and extract PE information. You can also use the MetadataReader class to read the assembly metadata.

C#
static async Task<bool> IsDotNetAssembly(string fileName)
{
    await using var stream = File.OpenRead(fileName);
    return IsDotNetAssembly(stream);
}

static bool IsDotNetAssembly(Stream stream)
{
    try
    {
        using var peReader = new PEReader(stream);
        if (!peReader.HasMetadata)
            return false;

        // If peReader.PEHeaders doesn't throw, it is a valid PEImage
        _ = peReader.PEHeaders.CorHeader;

        var reader = peReader.GetMetadataReader();
        return reader.IsAssembly;
    }
    catch (BadImageFormatException)
    {
        return false;
    }
}

Note 1: For .NET applications, the EXE file is a native application (App Host). To find the associated .NET assembly, check whether a DLL with the same name as the EXE exists.

Note 2: To detect a .NET application published as a single file, see the ILSpy source code for bundle detection (SingleFileBundle).

Do you have a question or a suggestion about this post? Contact me!

Follow me:
Enjoy this blog?