如何用C#反射判断.NET DLL属于.NET Core还是.NET Framework?
判断.NET DLL所属框架类型的C#实现方案
方法1:通过System.Reflection.Metadata读取目标框架属性(推荐,无需加载DLL)
该方法无需将DLL加载到当前应用程序域,完全避免兼容性风险,是最安全的判断方式。
步骤:
- 安装NuGet包:
System.Reflection.Metadata和System.Reflection.PortableExecutable - 编写代码读取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
相关产品推荐
相关产品推荐

