You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#反射判断.NET DLL属于.NET Core还是.NET Framework?

判断.NET DLL所属框架类型的C#实现方案

方法1:通过System.Reflection.Metadata读取目标框架属性(推荐,无需加载DLL)

该方法无需将DLL加载到当前应用程序域,完全避免兼容性风险,是最安全的判断方式。

步骤:

  1. 安装NuGet包:System.Reflection.Metadata 和 System.Reflection.PortableExecutable
  2. 编写代码读取PE文件中的TargetFrameworkAttribute,该属性明确标记了DLL的目标框架:
using System;
using System.IO;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
using System.Linq;

public static string GetTargetFramework(string dllPath)
{
    using var stream = new FileStream(dllPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    using var peReader = new PEReader(stream);
    
    if (!peReader.HasMetadata)
        return null; // 非.NET DLL
    
    var metadataReader = peReader.GetMetadataReader();
    var assemblyDef = metadataReader.GetAssemblyDefinition();
    
    foreach (var attrHandle in assemblyDef.GetCustomAttributes())
    {
        var attr = metadataReader.GetCustomAttribute(attrHandle);
        if (attr.Constructor.IsNil) continue;
        
        var ctorRef = metadataReader.GetMemberReference((MemberReferenceHandle)attr.Constructor);
        var typeRef = metadataReader.GetTypeReference((TypeReferenceHandle)ctorRef.Parent);
        
        if (metadataReader.GetString(typeRef.Name) == "TargetFrameworkAttribute")
        {
            var blobReader = metadataReader.GetBlobReader(attr.Value);
            blobReader.ReadByte(); // 跳过前缀标识字节
            return blobReader.ReadUTF8(blobReader.ReadCompressedInteger());
        }
    }
    
    return null;
}

// 使用示例
var targetFramework = GetTargetFramework(@"C:\path\to\your.dll");
bool isNetCoreOrModern = targetFramework?.StartsWith(".NETCoreApp") == true || targetFramework?.StartsWith(".NET") == true;
bool isNetFramework = targetFramework?.StartsWith(".NETFramework") == true;

方法2:使用AssemblyName读取元数据(轻量,无需加载DLL到AppDomain)

AssemblyName.GetAssemblyName仅读取DLL的元数据,不会将其加载到当前应用程序域,兼容性较好:

using System;
using System.Reflection;
using System.Linq;

public static bool IsNetCoreOrNet5PlusDll(string dllPath)
{
    try
    {
        var assemblyName = AssemblyName.GetAssemblyName(dllPath);
        var tfAttr = assemblyName.GetCustomAttributesData()
            .FirstOrDefault(ad => ad.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute");
        
        if (tfAttr == null) return false;
        
        var tfValue = tfAttr.ConstructorArguments[0].Value.ToString();
        return tfValue.StartsWith(".NETCoreApp") || tfValue.StartsWith(".NET");
    }
    catch (BadImageFormatException)
    {
        return false; // 非.NET DLL
    }
}

public static bool IsNetFrameworkDll(string dllPath)
{
    try
    {
        var assemblyName = AssemblyName.GetAssemblyName(dllPath);
        var tfAttr = assemblyName.GetCustomAttributesData()
            .FirstOrDefault(ad => ad.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute");
        
        if (tfAttr != null)
        {
            var tfValue = tfAttr.ConstructorArguments[0].Value.ToString();
            return tfValue.StartsWith(".NETFramework");
        }
        // 兼容无TargetFrameworkAttribute的旧版.NET Framework DLL
        var clrVersion = assemblyName.ImageRuntimeVersion;
        return clrVersion.StartsWith("v2.0") || clrVersion.StartsWith("v4.0");
    }
    catch (BadImageFormatException)
    {
        return false; // 非.NET DLL
    }
}

方法3:检查PE头中的CLR运行时版本

通过读取PE文件的CorHeader字段,可通过CLR版本号区分框架类型,适合无法读取TargetFrameworkAttribute的场景:

using System;
using System.IO;

public static string GetDllFrameworkType(string dllPath)
{
    using var stream = new FileStream(dllPath, FileMode.Open, FileAccess.Read);
    using var reader = new BinaryReader(stream);
    
    // 读取DOS头定位PE头
    stream.Seek(0x3C, SeekOrigin.Begin);
    var peHeaderOffset = reader.ReadInt32();
    
    // 验证PE标识
    stream.Seek(peHeaderOffset, SeekOrigin.Begin);
    if (reader.ReadUInt32() != 0x00004550) return null; // "PE\0\0"
    
    // 跳转至可选PE头的数据目录区
    stream.Seek(peHeaderOffset + 24 + 224, SeekOrigin.Begin);
    var dataDirCount = reader.ReadUInt16();
    if (dataDirCount < 15) return null;
    
    // 读取CLR运行时头位置
    stream.Seek(peHeaderOffset + 24 + 224 + 15 * 8, SeekOrigin.Begin);
    var clrHeaderOffset = reader.ReadUInt32();
    var clrHeaderSize = reader.ReadUInt32();
    if (clrHeaderOffset == 0 || clrHeaderSize == 0) return null;
    
    // 读取CLR版本号
    stream.Seek(clrHeaderOffset + 4, SeekOrigin.Begin);
    var major = reader.ReadUInt16();
    var minor = reader.ReadUInt16();
    var build = reader.ReadUInt16();
    var revision = reader.ReadUInt16();
    
    if (major == 2 && minor == 0)
        return ".NET Framework";
    if (major == 4 && minor == 0)
        return build >= 30319 && revision >= 42000 ? ".NET Core/.NET 5+" : ".NET Framework";
    
    return null;
}

场景适配建议

在你的两个应用版本中:

  • .NET Core版本仅允许加载IsNetCoreOrNet5PlusDll返回true的DLL
  • .NET Framework版本仅允许加载IsNetFrameworkDll返回true的DLL

内容的提问来源于stack exchange,提问作者user788454

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:05:18