Determinar a versão de estrutura (CLR) do assembly

A partir da linha de comando (ou por qualquer meio, na verdade), como posso determinar qual versão do CLR um assembly .NET requer?

Eu preciso determinar se um assembly requer versão 2.0 ou 4.0 CLR.

ildasm.exe irá mostrá-lo se você clicar duas vezes em “MANIFEST” e procurar por “Metadata version”. Por padrão, é a versão com a qual a imagem foi compilada.

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

Compile e execute o aplicativo acima sob o .NET Framework mais recente (como um CLR antigo pode não conseguir carregar assemblies que requerem um CLR mais recente) e execute-o passando o caminho para o assembly que você deseja verificar como o argumento da linha de comando.

Um esclarecimento …

O problema com todos os methods mencionados é que eles retornarão a versão 4.0 se o assembly foi compilado com o .NET framework 4.0, 4.5 ou 4.5.1.

A maneira de descobrir essa versão programaticamente no tempo de execução está usando o System.Runtime.Versioning.TargetFrameworkAttribute para o assembly fornecido, por exemplo

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

Retornará

 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 

Aqui está um equivalente ao PowerShell do código .NET sugerido em outra resposta. Usar o PowerShell significa que você pode pular algumas etapas, como criar e compilar uma assembly.

Em um prompt do PowerShell, execute o seguinte:

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

Por padrão, o PowerShell usa o runtime do .NET v2, portanto, você obterá uma exceção para os assemblies que segmentam a v4. Pergunta de estouro de pilha Como posso executar o PowerShell com o tempo de execução do .NET 4? detalha methods para alterar isso, se necessário.

Da linha de comando

DUMPBIN sua dll / exe / CLRHEADER

Eu sugiro usar ReflectionOnlyLoadFrom () insted de LoadFrom ()

Ele tem uma vantagem que pode carregar assemblies x64 e ia64 ao executar na máquina x86, enquanto o LoadFrom () não conseguirá fazer isso.

Embora ainda não carregue os assemblies .Net 4.0 de um powershell 2.0.

Como sugeriu @mistika, é melhor usar ReflectionOnlyLoadFrom() vez de LoadFrom() . A desvantagem disso é que chamar GetCustomAttributes() em um assembly carregado com ReflectionOnlyLoadFrom() lança uma exceção. Você precisa chamar GetCustomAttributesData() vez disso:

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

Uma ferramenta muito legal é o JustDecompile da Telerik. Você pode abrir assemblies e a ferramenta está mostrando se eles estão segmentando 4.5, 4.5.1 ou 4.6

Aqui está um forro powerhell que exibirá a versão do framework Target para assemblies que segmentam v4 e acima.

  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 

usar:

 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" 

Se você quiser include o resultado em um script, recomendo usar a saída de texto de ildasm.exe e, em seguida, grep “Version String” da saída.

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

Observe que incluo um ‘para que o comando find não reconheça “Comprimento da string de versão”

Tente este executável de Informações da Montagem para obter a versão do assembly, que informa a versão do CLR que ele requer e também outras informações, como opções de Compilação, Processador de Destino e Referências:

insira a descrição da imagem aqui