如何找出可执行文件需要运行的.NET Framework版本?

114

我有一个可执行文件,想知道这个文件需要哪个版本的Microsoft .NET Framework才能运行。

是否有简单的方法可以找到这些信息?

(目前我尝试了ILDASMDUMPBIN但没有成功。)


1
另请参见https://dev59.com/yHA75IYBdhLWcg3wH1TP?tab=oldest#tab-top - Ruben Bartelink
https://learn.microsoft.com/en-us/sysinternals/downloads/ -- Process Explorer非常出色且易于使用,只需以管理员身份运行即可。 - AquaAlex
11个回答

87

使用三十年历史、大小为200kb、预装工具 Notepad

  • notepad appname.exe 打开应用程序,
  • 查找单词framework
  • 使用 F3 重复上次搜索,直到出现 .NET Framework,version=vX.Y
  • 如果找不到任何内容(版本低于3.0),则搜索 v2. ……这比安装几个GB的.NET分析工具和垃圾工作室简单了100倍。

更新:在评论中,Thought 和 Marcus 建议搜索术语也可以是 netstandardnetframework


1
这很棒-特别是如果您没有访问反编译/其他工具的权限。 - Craig
3
更新:可能找不到该文件,而会出现一个“.NETStandard,version = ...”文件。 - Thought
1
更新:在我刚刚验证的应用程序中,该字符串不包括空格:.NETFramework,Version = v4.7.2 - Marcus
我的 .exe (winforms) 没有任何上述的字符串。 - Zoli

55

我认为你可以可靠地确定所需的CLR版本。您可以使用ILDASM并查看“ MANIFEST”节点或使用Reflector查看“ Application.exe”节点作为IL的反汇编视图来执行此操作。在两种情况下,都有一个注释指示CLR版本。在ILDASM中,注释是“//元数据版本”,而在Reflector中,注释是“目标运行时版本”。

以下是名为WindowsFormsApplication1.exe的.NET WinForms应用程序的示例:

ILDASM:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}
.assembly extern System
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 2:0:0:0
}

反射器:

.module WindowsFormsApplication1.exe
.subsystem 0x0002
// MVID: {CA3D2090-16C5-4899-953E-4736D6BC0FA8}
// Target Runtime Version: v2.0.50727

你还可以查看引用程序集的列表,并查找版本号最高的引用。

同样地,使用ILDASM查看“MANIFEST”节点数据:

.assembly extern System.Drawing
{
  .publickeytoken = (B0 3F 5F 7F 11 D5 0A 3A )                         // .?_....:
  .ver 2:0:0:0
}
.assembly extern System.Core
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )                         // .z\V.4..
  .ver 3:5:0:0
}

使用 Reflector 工具,查看列出的每个引用的反汇编(仍为 IL 代码):

.assembly extern System.Core
{
    .ver 3:5:0:0
    .publickeytoken = (B7 7A 5C 56 19 34 E0 89)
}

通过查找具有最高版本元数据的引用,您可以确定该引用来自哪个版本的框架,这将表明您需要安装相同版本的框架才能运行应用程序。话虽如此,我不认为这是100%可靠的,但我认为它不会很快改变。


4
不幸的是,微软引入了一个破坏性的变化来影响上述技术。.NET 4.5程序集无法在.NET 4上直接运行,要识别.NET 4.5程序集,您还需要读取System.Runtime.Versioning.TargetFrameworkAttribute。 http://www.lextm.com/2013/02/how-to-tell-net-45-only-assemblies.html - Lex Li
@LexLi的链接无法使用 - Zoli
1
@Zoli https://halfblood.pro/how-to-tell-net-4-5-only-assemblies-f5e9041533bb - Lex Li
1
@Zoli https://halfblood.pro/how-to-tell-net-4-5-only-assemblies-f5e9041533bb - undefined

36
更简单的方法是使用dotPeek,查看树中显示了什么。
请参见属性面板:enter image description here

27
现在您可以使用ILSpy来检查程序集的目标框架。加载程序集后,点击程序集节点的根部,您可以在TargetFramework声明下找到信息:
[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]

2
请注意,TargetFrameworkAttribute 仅在 .NET 4.0 中添加,因此不会出现在针对 .NET 3.5 或更早版本编译的程序集中。 - Wai Ha Lee
1
当单击已加载程序集的根节点时,ILSpy在注释中显示“Runtime: vXXX”。我能够看到一个v1.1.4322框架项目。 - ryancdotnet
它显示给我: // 架构:x64 // 运行时:.NET 4.0 - Zoli

16

From the command line: find "Framework" MyApp.exe


注意:大小写敏感,"findframework"(小写f)将不起作用。 - Vinicius Gonçalves
无法工作。我在我的WinForms .exe中得到的结果只有PresentationFramework - Zoli

15

你可以使用 Assembly.ImageRuntimeVersion 来获取版本信息,但是最好的做法可能是使用 Reflector 工具查看引用了哪个版本的 mscorlib

编辑:更好的方法是使用ILDASM,打开程序集并查看程序集清单。清单的第一行将告诉您程序集针对哪个版本的 CLR 构建。


4
这是错误的,原帖问的是.NET Framework的版本,而不是CLR Runtime的版本。这个回答解决了后者。例如,我正在使用Framework 4.7.2531.0,它使用CLR Runtime版本4.0.30139。ImageRuntimeVersion返回CLR版本,而不是Framework版本。 - Tom Baxter

12
您可以使用一个名为CorFlags.exe的工具。这个工具从.NET 2.0就开始存在,我确定它包含在Windows SDK 7.0中。默认情况下(在Windows XP Pro上),它被安装在C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\CorFlags.exe。向它提供托管模块的文件路径(不需要其他命令行标记)即可显示其头信息,其中包括版本。
请注意,此实用程序旨在修改模块的PE32头,因此在仔细阅读文档之前,请勿使用任何标志。

3
无法区分 .Net4 和 .Net4.5。 - mheyman

6
您可以使用Powershell在Windows中获取文件的.NET版本。以下是脚本;
$path=’.\’
$ErrorActionPreference = "SilentlyContinue"
$files=Get-ChildItem -Path $path -Recurse -include *.dll,*.exe
foreach($file in $files)
{
    $filename = $file.BaseName
    $version = $([System.Reflection.Assembly]::ReflectionOnlyLoadFrom($file.FullName).GetCustomAttributesData() |
                 select-object -ExpandProperty ConstructorArguments | 
                 select-object -ExpandProperty Value | 
                 select-string -Pattern '.NET')
    Write-Output "$filename,$version"
}

提供如下结果:在此输入图片描述

请注意,该结果提取了该文件夹中exe文件的.NET版本,但对于dll文件也会执行相同的操作。


1
这对我没用。我将所有内容复制并粘贴到 PowerShell 中,将路径更改为 exe 路径,但它只告诉我应用程序的名称,没有其他信息。 - edo101
做得很好;要在 PowerShell Core 中使其正常工作,请将 ReflectionOnlyLoadFrom 替换为 LoadFile - mklement0
和我一样,没有提到我的Winforms exe,只有文件名被打印。 - Zoli

2

或者你可以找出它引用的System.Core版本。这将告诉你这个应用程序使用的.NET Framework版本。对于2.0,System.Core的版本将是2.0.xxx.xxx。对于3.5,版本将是3.5.xxx.xxx等。


1
我不认为这是正确的。我有一个目标框架为4.5,但使用了System.Core 4.0.XXX.XXX。 - Paul Totzke

2
在Linux/OSX/unix系统中,您可以使用以下命令:
strings that_app.exe | grep 'v2.\|Framework'

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接