Определить версию сборки (CLR) сборки

Из командной строки (или каким-либо образом на самом деле), как я могу определить, какая версия CLR требует assembly .NET ?

Мне нужно определить, требует ли assembly 2.0 или 4.0 версии CLR.

ildasm.exe покажет его, если вы дважды щелкните «МАНИФЕСТ» и ищите «версию метаданных». По умолчанию это версия, с которой было скомпилировано изображение.

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

Скомпилируйте и запустите указанное приложение в последней платформе .NET Framework (поскольку более ранняя среда CLR может не иметь возможности загружать сборки, требующие новой CLR) и запускать ее, передавая путь к сборке, которую вы хотите проверить, в качестве аргумента командной строки.

Одно уточнение …

Проблема со всеми упомянутыми методами заключается в том, что они вернут версию 4.0, если assembly была скомпилирована против .NET framework 4.0, 4.5 или 4.5.1.

Способ программирования этой версии программно во время выполнения использует 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().First(); Console.WriteLine(attribute.FrameworkName); Console.WriteLine(attribute.FrameworkDisplayName); 

Вернется

 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 

Вот эквивалент PowerShell кода .NET, предложенный в другом ответе. Использование PowerShell означает, что вы можете пропустить несколько шагов, таких как создание и компиляция сборки.

В командной строке PowerShell запустите следующее:

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

По умолчанию PowerShell использует среду выполнения .NET v2, поэтому вы получите исключение для ассемблеров, нацеленных на v4. Вопрос о переполнении стека Как запустить PowerShell с помощью среды выполнения .NET 4? детализирует методы для их изменения, если это необходимо.

Из командной строки

DUMPBIN ваша dll / exe / CLRHEADER

Я бы предложил использовать ReflectionOnlyLoadFrom () insted из LoadFrom ()

Преимущество состоит в том, что он может загружать сборки x64 и ia64 при работе на компьютере x86, а LoadFrom () не сможет этого сделать.

Хотя он по-прежнему не будет загружать .Net 4.0 сборки из 2.0 powershell.

Ниже приведена shell powershell, в которой будет отображаться версия Target framework для ассемблеров, ориентированных на 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 

использовать:

 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" 

Как предположил @mistika, лучше использовать ReflectionOnlyLoadFrom() а не LoadFrom() . Недостатком этого является то, что вызов GetCustomAttributes() на сборке, загруженной ReflectionOnlyLoadFrom() вызывает исключение. GetCustomAttributesData() этого вам нужно вызвать 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); 

Очень хороший инструмент – JustDecompile от Telerik. Вы можете открывать сборки, и инструмент показывает, нацелены ли они на 4.5, 4.5.1 или 4.6

Если вы хотите включить результат в скрипт, я рекомендую использовать текстовый вывод ildasm.exe , а затем grep «Version String» из вывода.

 "C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1A\bin\NETFX 4.5.1 Tools\ildasm.exe" /text D:\LocalAssemblies\Toolfactory.Core.BaseTypes.dll /noil /headers | find "' Version String" 

Примечание. Я включаю команду «так что команда find не распознает« Длина строки строки »,

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

введите описание изображения здесь

  • Как вы прокручиваете загруженные в настоящее время сборки?
  • Как загрузить сборку во время выполнения перед событием AssemblyResolve?
  • Как получить вывод ассемблера из источника C / C ++ в gcc?
  • В чем разница между MOV и LEA?
  • Примеры предварительной выборки?
  • Код C ++ для проверки гипотезы Collatz быстрее, чем assembly вручную - почему?
  • Как точно работает инструкция x86 LOOP?
  • Почему XCHG reg, reg 3 инструкции по микрооперации на современных архитектурах Intel?
  • Самый быстрый способ вычисления 128-битного целого по модулю 64-разрядного целого числа
  • C #: зачем подписывать сборку?
  • Определите, были ли сборки .NET построены из одного источника
  • Давайте будем гением компьютера.