.net 确定程序集的框架 (CLR) 版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2310701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 13:57:30  来源:igfitidea点击:

Determine framework (CLR) version of assembly

.netassembliesversion

提问by Klaus Byskov Pedersen

From the command line (or by any means really), how can I determine which CLRversion a .NETassembly requires?

从命令行(或通过任何方式),我如何确定.NET程序集需要哪个CLR版本?

I need to determine if an assembly requires 2.0 or 4.0 CLR version.

我需要确定程序集是否需要 2.0 或 4.0 CLR 版本。

回答by Darin Dimitrov

ildasm.exewill show it if you double-click on "MANIFEST" and look for "Metadata version". By default, it's the version that the image was compiled against.

ildasm.exe如果您双击“清单”并查找“元数据版本”,则会显示它。默认情况下,它是编译映像所针对的版本。

回答by Fernando Gonzalez Sanchez

One clarification...

一澄清...

The problem with all the mentioned methods is that they will return version 4.0 if assembly was compiled against .NET framework 4.0, 4.5 or 4.5.1.

所有提到的方法的问题是,如果程序集是针对 .NET 框架 4.0、4.5 或 4.5.1 编译的,它们将返回 4.0 版。

The way to figure out this version programmatically at runtime is using the System.Runtime.Versioning.TargetFrameworkAttribute for the given assembly, for example

例如,在运行时以编程方式确定此版本的方法是使用给定程序集的 System.Runtime.Versioning.TargetFrameworkAttribute

using System;
using System.Linq;
using System.Reflection;
using System.Runtime.Versioning;

...    

object[] list = Assembly.GetExecutingAssembly().GetCustomAttributes(true);
var attribute = list.OfType<TargetFrameworkAttribute>().First();

Console.WriteLine(attribute.FrameworkName);
Console.WriteLine(attribute.FrameworkDisplayName);

Will return

将返回

a.FrameworkName ".NETFramework,Version=v4.0"    string
a.FrameworkDisplayName  ".NET Framework 4"      string

a.FrameworkName ".NETFramework,Version=v4.5"    string
a.FrameworkDisplayName  ".NET Framework 4.5"    string

a.FrameworkName ".NETFramework,Version=v4.5.1"  string
a.FrameworkDisplayName  ".NET Framework 4.5.1"  string

回答by Mehrdad Afshari

class Program {
  static void Main(string[] args) { 
      System.Console.WriteLine(
             System.Reflection.Assembly.LoadFrom(args[0]).ImageRuntimeVersion);
  }
}

Compile and run the above application under the latest .NET Framework (as an older CLR may be unable to load assemblies requiring a newer CLR) and run it passing the path to the assembly you want to check as the command line argument.

在最新的 .NET Framework 下编译并运行上述应用程序(因为较旧的 CLR 可能无法加载需要较新 CLR 的程序集)并运行它,将要检查的程序集的路径作为命令行参数传递给它。

回答by Robin Minto

Here's a PowerShellequivalent of the .NET code suggested in another answer. Using PowerShell means that you can skip a few steps like creating and compiling an assembly.

这是另一个答案中建议的 .NET 代码的PowerShell等效项。使用 PowerShell 意味着您可以跳过创建和编译程序集等几个步骤。

At a PowerShell prompt, run the following:

在 PowerShell 提示符下,运行以下命令:

[System.Reflection.Assembly]::LoadFrom("C:\...\MyAssembly.dll").ImageRuntimeVersion

By default, PowerShell uses the .NET v2 runtime, so you'll get an exception for assemblies targetting v4. Stack Overflow question How can I run PowerShell with the .NET 4 runtime?details methods for changing that, if required.

默认情况下,PowerShell 使用 .NET v2 运行时,因此您将收到面向 v4 的程序集的异常。堆栈溢出问题如何使用 .NET 4 运行时运行 PowerShell?如果需要,详细说明更改方法。

回答by Anders Forsgren

Here is a powershell one liner that will display the Target framework versionfor assemblies targeting v4 and up.

这是一个 powershell one liner,它将显示面向 v4 及更高版本的程序集的目标框架版本

 Resolve-Path($args) | Select @{N='Assembly'; E={$_ }}, @{N='TargetFramework'; E={(([Reflection.Assembly]::ReflectionOnlyLoadFrom($_).GetCustomAttributesData() | Where-Object { $_.AttributeType -like "System.Runtime.Versioning.TargetFrameworkAttribute" })).NamedArguments.TypedValue}} | Format-Table

use:

用:

C:\test\> show-targetfw.ps1 *.dll

Assembly             TargetFramework
--------             --------
C:\test\a.dll        ".NET Framework 4.6.1"
C:\test\b.dll        ".NET Framework 4.5.2"

回答by Tinku

From command line

从命令行

DUMPBIN your dll/exe /CLRHEADER

转储你的 dll/exe /CLRHEADER

回答by mistika

I'd suggest using ReflectionOnlyLoadFrom() insted of LoadFrom()

我建议使用 ReflectionOnlyLoadFrom() insted of LoadFrom()

It has an advantage that it can load x64 and ia64 assemblies when running on x86 machine, while LoadFrom() will fail to do that.

它的一个优势是它可以在 x86 机器上运行时加载 x64 和 ia64 程序集,而 LoadFrom() 将无法这样做。

Though it still won't load .Net 4.0 assemblies from a 2.0 powershell.

虽然它仍然不会从 2.0 powershell 加载 .Net 4.0 程序集。

回答by Andy

As @mistika suggested, it is better to use ReflectionOnlyLoadFrom()rather than LoadFrom(). The downside of this is that calling GetCustomAttributes()on an assembly loaded with ReflectionOnlyLoadFrom()throws an exception. You need to call GetCustomAttributesData()instead:

正如@mistika 所建议的,最好使用ReflectionOnlyLoadFrom()而不是LoadFrom(). 这样做的缺点是调用GetCustomAttributes()加载了的程序集会ReflectionOnlyLoadFrom()引发异常。您需要改为调用GetCustomAttributesData()

var assembly = Assembly.ReflectionOnlyLoadFrom(assemblyPath);
var customAttributes = assembly.GetCustomAttributesData();
var targetFramework = customAttributes.FirstOrDefault(attr => attr.AttributeType.Equals(typeof(TargetFrameworkAttribute)));

var frameworkName = string.Empty;
var frameworkDisplayName = string.Empty;
if (null != targetFramework)
{
    if(targetFramework.ConstructorArguments.Any())
    {
        // first argument is the name of the framework.
        frameworkName = (string)targetFramework.ConstructorArguments[0].Value;
    }

    // search for a named argument called "FrameworkDisplayName"
    var frameworkDisplayNameArg = targetFramework.NamedArguments.FirstOrDefault(arg => arg.MemberName.Equals("FrameworkDisplayName"));
    if (null != frameworkDisplayNameArg)
    {
        frameworkDisplayName = (string)frameworkDisplayNameArg.TypedValue.Value;
    }
}

Console.WriteLine("Framework Name: " + frameworkName);
Console.WriteLine("Framework Display Name: " + frameworkDisplayName);

回答by xr280xr

I use ILSpy as a replacement for Reflector. If you open the assembly in ILSpy, you can see, for example:

我使用 ILSpy 作为 Reflector 的替代品。如果您在 ILSpy 中打开该程序集,您可以看到,例如:

[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]

[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]

回答by xforfun

A very nice tool is JustDecompile from Telerik. You can open assemblies and the tool is showing whether they are targeting 4.5, 4.5.1 or 4.6

Telerik 的 JustDecompile 是一个非常好的工具。您可以打开程序集,该工具会显示它们是针对 4.5、4.5.1 还是 4.6