我有一个旧的 dll,它是针对 .NET 框架编译并部署的。我不确定它是针对哪个版本的 .NET 框架进行编译的。我想知道如何确定该 dll 是针对哪个版本的 .NET 框架进行编译的?我无法信任源代码,因为我相信它已升级到 Visual Studio 2008 并更改为 .NET Framework 版本 3.5。
在 PowerShell 中,您可以使用以下命令来获取目标运行时:
$path = "C:\Some.dll"
[Reflection.Assembly]::ReflectionOnlyLoadFrom($path).ImageRuntimeVersion
我根据 Ben Griswold 的回答将其改编为 PowerShell。
如果你想知道 Visual Studio 中指定的目标框架版本,请使用:
$path = "C:\Some.dll"
[Reflection.Assembly]::ReflectionOnlyLoadFrom($path).CustomAttributes |
Where-Object {$_.AttributeType.Name -eq "TargetFrameworkAttribute" } |
Select-Object -ExpandProperty ConstructorArguments |
Select-Object -ExpandProperty value
你应该得到类似的东西
.NETFramework,版本=v4.5.2
dotPeek 是一个很棒的(免费)工具来显示此信息。
如果您在使用 Reflector 时遇到一些问题,那么这是一个不错的选择。
您可以使用ILDASM...
ildasm.exe C:\foo.dll /metadata[=MDHEADER] /text /noil
并检查输出中的“元数据部分”。会是这样的:
元数据部分:0x424a5342,版本:1.1,额外:0,版本长度: 12、版本:v4.0.30319
“版本”标签将告诉您 .NET Framework 版本。在上面的示例中,它是 4.0.30319
将其加载到Reflector并查看它引用了什么?
例如:
您有几个选择:要以编程方式从托管代码中获取它,请使用 Assembly.ImageRuntimeVersion:
Dim a As Assembly = Reflection.Assembly.ReflectionOnlyLoadFrom("C:\path\assembly.dll")
Dim s As String = a.ImageRuntimeVersion
在命令行中,从 v2.0 开始,如果双击“MANIFEST”并查找“元数据版本”,ildasm.exe 将显示它。 确定图像的 CLR 版本
使用 ILSpy http://ilspy.net/
开源、免费,绝对是一个选择,因为现在 Reflector 是付费的。
就这么简单
var tar = (TargetFrameworkAttribute)Assembly
.LoadFrom("yoursAssembly.dll")
.GetCustomAttributes(typeof(TargetFrameworkAttribute)).First();
使用 ILDASM 反编译它,然后查看正在引用的 mscorlib 版本(应该几乎位于顶部)。
如果您有 JetBrains 的 dotPeek,您可以在 Assembly Explorer 中看到它。
我快速编写了这个 C# 控制台应用程序来执行此操作:
https://github.com/stuartjsmith/binarydetailer
只需传递一个目录作为参数,它就会尽力告诉您其中每个 dll 和 exe 的网络框架
“Detect It Easy”也称为 DiE,是一个用于确定文件类型的程序。适用于 .dll 文件或其他 (.exe) 文件。商业和非商业用途绝对免费。
使用“读取dll文本内容”的方式:
private static readonly Regex CompiledNetCoreRegex = new Regex(@".NETCoreApp,Version=v[0-9\.]+", RegexOptions.Compiled);
private static readonly Regex CompiledNetFrameworkRegex = new Regex(@".NETFramework,Version=v[0-9\.]+", RegexOptions.Compiled);
// You can define other methods, fields, classes and namespaces here
public string GetTargetFramework(FileInfo dll)
{
string contents = File.ReadAllText(dll.FullName);
Match match = CompiledNetCoreRegex.Match(contents);
if (match.Success)
{
return match.Value;
}
match = CompiledNetFrameworkRegex.Match(contents);
if (match.Success)
{
return match.Value;
}
return "unable to compute target framework";
}
扩展此处的答案,如果存在依赖程序集,则可能会崩溃。如果您很幸运并且知道受抚养人在哪里(或者更幸运的是,在 GAC 中),那么这可能会有所帮助...
using System.Reflection;
using System.Runtime.Versioning;
// ...
{
AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += new ResolveEventHandler(CurrentDomain_ReflectionOnlyAssemblyResolve);
var asm = System.Reflection.Assembly.LoadFrom(@"C:\Codez\My.dll");
var targetFrameAttribute = asm.GetCustomAttributes(true).OfType<TargetFrameworkAttribute>().FirstOrDefault();
targetFrameAttribute.Dump();
}
Assembly CurrentDomain_ReflectionOnlyAssemblyResolve(object sender, ResolveEventArgs args)
{
var name = args.Name;
if (name.StartsWith("Depends"))
return System.Reflection.Assembly.ReflectionOnlyLoadFrom(@"C:\Codez\Depends.dll");
return System.Reflection.Assembly.ReflectionOnlyLoad(args.Name);
}
参考:https://weblog.west-wind.com/posts/2006/Dec/22/Reflection-on-Problem-Assemblies
如果您使用的是 Linux 并且有单声道,我认为您可以使用
ikdasm
而不是 ildasm.exe
。
我不太明白这个,所以我不知道它是否准确。但我做了一个简单的测试,编译了一个dll库,只改变了
<TargetFramework>
。然后我在输出(bin)目录上运行这个:
ikdasm -assemblyref lib.dll
每个目标框架的结果都不同。
net8.0
AssemblyRef Table
1: Version=8.0.0.0
Name=System.Runtime
Flags=0x00000000
Public Key:
0x00000000: B0 3F 5F 7F 11 D5 0A 3A
netstandard2.0
AssemblyRef Table
1: Version=2.0.0.0
Name=netstandard
Flags=0x00000000
Public Key:
0x00000000: CC 7B 13 FF CD 2D DD 51
net4.8
AssemblyRef Table
1: Version=4.0.0.0
Name=mscorlib
Flags=0x00000000
Public Key:
0x00000000: B7 7A 5C 56 19 34 E0 89
这个似乎只显示主要版本,所以:
ikdasm -customattr lib.dll | grep System.Runtime.Versioning.TargetFrameworkAttribute
5: Assembly: 1 instance void class [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::'.ctor'(System.String) [".NETFramework,Version=v4.8", {FrameworkDisplayName = ""}]