Как узнать, какую версию.NET Framework должен запускать исполняемый файл?

У меня есть исполняемый файл, и я хотел бы знать, какие версии.NET Framework этот файл должен быть запущен.

Есть ли простой способ найти эту информацию где-нибудь?

(До сих пор я безуспешно пробовал ILDASM и DUMPBIN.)

11 ответов

Решение

Я думаю, что самое близкое, что вы можете получить, это определить, какая версия CLR требуется. Вы можете сделать это, используя ILDASM и просматривая узел "MANIFEST" или Reflector и просматривая представление "disasembly" узла "Application.exe" как IL. В обоих случаях есть комментарий, который указывает версию CLR. В ILDASM комментарий - это "// версия метаданных", а в Reflector - "Целевая версия времени выполнения".

Вот примеры для приложения.NET WinForms с именем WindowsFormsApplication1.exe:

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)
}

Найдя ссылку с метаданными наивысшей версии, вы можете определить, из какой версии Framework была получена эта ссылка, что указывало бы на то, что для запуска приложения вам необходима та же версия Framework. При этом я бы не отнесся к этому как к 100% надежному, но я не думаю, что это скоро изменится.

Используя Блокнот, три десятилетия, размером 200 КБ, предустановленный инструмент:

  • открыть приложение с notepad appname.exe,
  • поиск по слову "рамки",
  • повторить последний поиск с F3 до тех пор .NET Framework,version=vX.Y появляется
  • если ничего не найдено (версии ниже 3.0) ищите v2.... все же в 100 раз проще, чем установка гигабайт инструментов анализатора точек сети и мусорных студий.

Любой другой редактор / программа просмотра также может открывать двоичные файлы, такие как Notepad++ или большой текстовый / hex-просмотрщик TotalCommander.

Более упрощенным подходом было бы использовать dotPeek и посмотреть, что отображается в дереве.

Смотрите панель свойств:

Теперь вы можете использовать ILSpy для проверки целевой структуры сборки. После загрузки сборки нажмите на корень узла сборки, и вы можете найти информацию в декларации TargetFramework:

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

Из командной строки: find "Framework" MyApp.exe

Из кода вы можете использовать Assembly.ImageRuntimeVersion но, посмотрев на файл, вероятно, лучше всего использовать отражатель и посмотреть, какая версия mscorlib на него ссылаются.

Изменить: Еще лучше было бы использовать ildasm, открыть свою сборку, а затем просмотреть манифест для сборки. Первая строка манифеста сообщит вам точную версию CLR, для которой была создана сборка.

Вы можете использовать инструмент под названием CorFlags.exe. Он существует с.NET 2.0, и я точно знаю, что он включен в Windows SDK 7.0. По умолчанию (в Windows XP Pro) он устанавливается в C:\Program Files\Microsoft SDKs\Windows\v7.0A\bin\CorFlags.exe. Укажите путь файла к управляемому модулю (без каких-либо других флагов командной строки) для отображения информации заголовка, включая версию.

Помните, что эта утилита предназначена для изменения заголовка PE32 модуля, поэтому не используйте какие-либо флаги, пока не внимательно прочитаете документацию.

Вы можете получить.NET-версию файла в Windows с помощью Powershell. Следующий скрипт;

$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"
}

дает следующий результат;

Обратите внимание, что в результате была извлечена версия.NET для exe-файлов в этой папке, но он также будет делать то же самое для dll.

Или вы можете просто узнать, какая ссылка на System.Core у него есть. Это скажет вам версию.NET Framework, которую использует это приложение. Для 2.0 версия System.Core будет 2.0.xxx.xxx. Для 3.5 версия будет 3.5.xxx.xxx и т. Д.

В Linux/OSX/unix вы можете использовать:

strings that_app.exe | grep 'v2.\|Framework'

Для более новых приложений .NET 6.0 метод блокнота у меня не работал, но если рядом с исполняемым файлом есть файл *.deps.json, это большая подсказка - часто содержит версию в виде следующего раздела

      "runtimeTarget": {
    "name": ".NETCoreApp,Version=v6.0/win-x86"

Изменить: в дальнейшем вы также можете найти пару файлов .exe и .dll с одинаковым именем, попробуйте открыть файл DLL в блокноте и выполнить поиск NETCoreApp, вы должны найти что-то вроде этого:

      .NETCoreApp,Version=v6.0
Другие вопросы по тегам