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

98

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

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

( До сих пор я пытался ILDASM и DUMPBIN без удачи.)

Сэм
источник
См. Также stackoverflow.com/questions/3460982/…
Рубен Бартелинк
docs.microsoft.com/en-us/sysinternals/downloads - Process Explorer делает это очень хорошо и легко в использовании, просто запустите его от имени администратора
AquaAlex

Ответы:

55

Я думаю, что самое надежное, что вы можете получить, это определить, какая версия CLR требуется. Вы можете сделать это, используя ILDASM и глядя на узел «MANIFEST» или Reflector и просматривая представление разборки узла «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% надежным, но не думаю, что в ближайшее время это изменится.

Скотт Дорман
источник
4
К сожалению, Microsoft вносит критическое изменение в описанный выше метод. Сборки .NET 4.5 не могут работать на чистом .NET 4, и чтобы сообщить сборке .NET 4.5, вам также необходимо прочитать System.Runtime.Versioning.TargetFrameworkAttribute. lextm.com/2013/02/how-to-tell-net-45-only-assemblies.html
Лекс Ли
57

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

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

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

Асаин Куйович
источник
Это здорово, особенно если у вас нет доступа к декомпиляции / другим инструментам,
Крейг
@BentTranberg интересно, не могли бы вы прислать мне как-нибудь exe, asainnp на gmail com.
Asain Kujovic 05
32

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

См. Панель свойств: введите описание изображения здесь

Дэниел А. Уайт
источник
22

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

[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
цандхол
источник
2
Обратите внимание, что TargetFrameworkAttribute был добавлен только в .NET 4.0, поэтому не будет присутствовать в сборках, скомпилированных для .NET 3.5 или более ранней версии .
Вай Ха Ли
ILSpy показывает "Runtime: vXXX" в комментариях, когда щелкает корневой узел загруженной сборки. Мне удалось увидеть фреймворк v1.1.4322.
ryancdotnet 01
15

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

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

Эндрю Хэйр
источник
3
Это не верно. OP спросил о версии .NET Framework, а не о версии среды выполнения CLR. Этот ответ касается последнего. В качестве примера я использую Framework 4.7.2531.0, в котором используется среда выполнения CLR версии 4.0.30139. ImageRuntimeVersion возвращает версию CLR, а не версию Framework.
Том Бакстер
11

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

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

Винс Федорчак
источник
2
Невозможно различить .Net4 и .Net4.5
mheyman
11

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

Шон Б.
источник
3

Вы можете получить .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.

Марк Уокер
источник
2

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

Денис
источник
Я не думаю, что это правда. У меня целевая платформа 4.5, но я использую System.Core 4.0.XXX.XXX
Пол Тотцке 01
1

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

strings that_app.exe | grep 'v2.\|Framework'
Pierz
источник