Como descobrir qual versão do .NET Framework um executável precisa ser executado?

97

Eu tenho um arquivo executável e gostaria de saber quais versões do .NET framework esse arquivo precisa ser iniciado.

Existe uma maneira fácil de encontrar essas informações em algum lugar?

(Até agora tentei ILDASM e DUMPBIN sem qualquer sorte.)

Sam
fonte
Veja também stackoverflow.com/questions/3460982/…
Ruben Bartelink
docs.microsoft.com/en-us/sysinternals/downloads - O Process Explorer faz isso muito bem e fácil de usar, basta executá-lo como administrador
AquaAlex

Respostas:

55

Acho que o mais próximo que você pode obter com segurança é determinar qual versão do CLR é necessária. Você pode fazer isso usando ILDASM e olhando para o nó "MANIFESTO" ou Refletor e olhando para a visualização de desmontagem do nó "Application.exe" como IL. Em ambos os casos há um comentário que indica a versão do CLR. No ILDASM, o comentário é "// Metadata version" e no Reflector o comentário é "Target Runtime Version".

Aqui estão alguns exemplos de um aplicativo .NET WinForms chamado 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
}

Refletor:

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

Você também pode examinar a lista de assemblies referenciados e procurar a referência com o maior número de versão.

Novamente, usando ILDASM olhando para os dados do nó "MANIFESTO":

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

E usando o refletor, olhando para a dissambly (ainda como IL) para cada referência listada:

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

Ao localizar a referência com os metadados da versão mais alta, você pode determinar de qual versão do Framework essa referência veio, o que indicaria que você precisa da mesma versão do Framework instalada para que o aplicativo seja executado. Dito isso, eu não trataria isso como 100% confiável, mas não acho que vai mudar tão cedo.

Scott Dorman
fonte
4
Infelizmente, a Microsoft introduz uma alteração significativa para a técnica acima. Os assemblies do .NET 4.5 não podem ser executados no .NET 4 bruto e, para informar um assembly do .NET 4.5, você também precisa ler System.Runtime.Versioning.TargetFrameworkAttribute. lextm.com/2013/02/how-to-tell-net-45-only-assemblies.html
Lex Li
56

Usando o Notepad , três décadas de idade, 200kb de tamanho, ferramenta pré-instalada:

  • abrir o aplicativo com notepad appname.exe,
  • pesquise a palavra "estrutura",
  • repita a última pesquisa com F3até .NET Framework,version=vX.Yaparecer
  • se nada for encontrado (versões abaixo de 3.0) pesquise v2.... ainda 100 vezes mais fácil do que instalar gigabytes de ferramentas de análise de ponto-net e estúdios de lixo.

Qualquer outro editor / espectador pode abrir binários também, como o Notepad ++ ou grande texto / hex telespectador do TotalCommander Lister .

Asain Kujovic
fonte
Isso é ótimo, especialmente se você não tiver acesso a descompilar / outras ferramentas
Craig
@BentTranberg interessante, você pode me enviar exe de alguma forma, asainnp no gmail com.
Asain Kujovic
32

Uma abordagem mais simplificada seria usar o dotPeek e ver o que aparece na árvore.

Veja o painel de propriedades: insira a descrição da imagem aqui

Daniel A. White
fonte
22

Agora você pode usar ILSpy para examinar a estrutura de destino de uma montagem. Depois de carregar a montagem, clique na raiz do nó da montagem, e você pode encontrar as informações na declaração TargetFramework:

[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
Tsandhol
fonte
2
Observe que TargetFrameworkAttribute foi adicionado apenas no .NET 4.0, portanto, não estará presente em assemblies compilados no .NET 3.5 ou anterior.
Wai Ha Lee
ILSpy mostra "Runtime: vXXX" em comentários ao clicar no nó raiz da montagem carregada. Consegui ver um projeto de estrutura v1.1.4322.
ryancdotnet
15

Você pode usar o código, Assembly.ImageRuntimeVersionmas olhando para o arquivo provavelmente a melhor coisa a fazer seria usar o reflector e ver qual versão do mscorlibestá sendo referenciada.

Edit: Ainda melhor seria usar ildasm , abrir sua montagem e visualizar o manifesto da montagem. A primeira linha do manifesto informará a versão exata do CLR para a qual o assembly foi criado.

Andrew Hare
fonte
3
Isto está errado. O OP perguntou sobre a versão do .NET Framework, não a versão do CLR Runtime. Esta resposta aborda o último. Como exemplo, estou executando o Framework 4.7.2531.0 que usa o CLR Runtime versão 4.0.30139. ImageRuntimeVersion retorna a versão CLR, não a versão Framework.
Tom Baxter
11

Você pode usar uma ferramenta chamada CorFlags.exe. Ele existe desde o .NET 2.0 e tenho certeza de que está incluído no Windows SDK 7.0. Por padrão (no Windows XP Pro), ele é instalado em C: \ Arquivos de programas \ Microsoft SDKs \ Windows \ v7.0A \ bin \ CorFlags.exe. Forneça a ele o caminho do arquivo para um módulo gerenciado (sem quaisquer outros sinalizadores de linha de comando) para exibir suas informações de cabeçalho, que incluem a versão.

Lembre-se de que este utilitário foi projetado para modificar o cabeçalho PE32 de um módulo, portanto, não use nenhum dos sinalizadores até ler a documentação com atenção.

Vince Fedorchak
fonte
1
Não é possível distinguir entre .Net4 e .Net4.5
mheyman
11

Na linha de comando: find "Framework" MyApp.exe

Sean B
fonte
2

Ou você pode apenas descobrir qual referência de System.Core ele possui. Isso informará a versão do .NET Framework que este aplicativo está usando. Para 2.0, a versão de System.Core será 2.0.xxx.xxx. Para 3.5, a versão será 3.5.xxx.xxx, etc.

Denis
fonte
Eu não acho que isso seja verdade. Eu tenho uma estrutura de destino de 4.5, mas uso System.Core 4.0.XXX.XXX
Paul Totzke
2

Você pode obter a versão .NET de um arquivo no Windows usando o Powershell. O seguinte script;

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

fornece o seguinte resultado; insira a descrição da imagem aqui

Observe que o resultado extraiu a versão .NET para os arquivos exe nessa pasta, mas também fará o mesmo para uma dll.

Mark Walker
fonte
1

No Linux / OSX / unix, você pode usar:

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