Jak sprawdzić, która wersja .NET Framework musi działać plik wykonywalny?

97

Mam plik wykonywalny i chciałbym wiedzieć, które wersje platformy .NET należy uruchomić.

Czy istnieje łatwy sposób na znalezienie gdzieś tych informacji?

(Do tej pory próbowałem ILDASM i DUMPBIN bez powodzenia).

Sam
źródło
Zobacz także stackoverflow.com/questions/3460982/…
Ruben Bartelink
docs.microsoft.com/en-us/sysinternals/downloads - Process Explorer robi to bardzo dobrze i jest łatwy w użyciu, wystarczy uruchomić go jako administrator
AquaAlex

Odpowiedzi:

55

Myślę, że najbliższym możliwym niezawodnym rozwiązaniem jest określenie, która wersja CLR jest wymagana. Można to zrobić, używając ILDASM i patrząc na węzeł „MANIFEST” lub reflektor i patrząc na widok demontażu węzła „Application.exe” jako IL. W obu przypadkach jest komentarz wskazujący na wersję CLR. W ILDASM komentarz to „// Wersja metadanych”, a w Reflektorze komentarz to „Docelowa wersja środowiska wykonawczego”.

Oto przykłady aplikacji .NET WinForms o nazwie 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
}

Reflektor:

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

Możesz również przejrzeć listę zestawów, do których istnieją odwołania, i poszukać odwołania o najwyższym numerze wersji.

Ponownie, używając ILDASM patrząc na dane węzła „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
}

I używając Reflectora, patrząc na dissambly (nadal jako IL) dla każdego wymienionego odniesienia:

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

Znajdując odwołanie z metadanymi najwyższej wersji, można określić, z której wersji Framework pochodzi, z którego pochodzi, co wskazywałoby, że do uruchomienia aplikacji potrzebna jest ta sama wersja Framework zainstalowana. Biorąc to pod uwagę, nie traktowałbym tego jako w 100% niezawodnego, ale nie sądzę, że wkrótce się to zmieni.

Scott Dorman
źródło
4
Niestety Microsoft wprowadza przełomową zmianę dla powyższej techniki. Zestawy .NET 4.5 nie mogą działać na surowym środowisku .NET 4, a aby poinformować zestaw .NET 4.5, należy również odczytać System.Runtime.Versioning.TargetFrameworkAttribute. lextm.com/2013/02/how-to-tell-net-45-only-assemblies.html
Lex Li
56

Używając Notatnika , sprzed trzech dekad, rozmiaru 200 KB, preinstalowanego narzędzia:

  • otwórz aplikację za pomocą notepad appname.exe,
  • wyszukaj słowo „framework”,
  • powtórz ostatnie wyszukiwanie za pomocą, F3.NET Framework,version=vX.Ypojawi się
  • jeśli nic nie zostanie znalezione (wersje poniżej 3.0), wyszukaj v2.... wciąż 100 razy łatwiejsze niż instalowanie gigabajtów narzędzi do analizowania sieci i śmieci.

Każdy inny edytor / przeglądarka może otworzyć pliki binarne też, jak Notepad ++ lub wielkim text / hex widza TotalCommander za Lister .

Asain Kujovic
źródło
To jest świetne - zwłaszcza jeśli nie masz dostępu do dekompilacji / innych narzędzi
Craig
@BentTranberg ciekawe, czy możesz mi jakoś wysłać exe, asainnp na gmail com.
Asain Kujovic
32

Bardziej uproszczonym podejściem byłoby użycie dotPeek i zobaczenie, co pojawia się w drzewie.

Zobacz panel właściwości: wprowadź opis obrazu tutaj

Daniel A. White
źródło
22

Możesz teraz użyć ILSpy do zbadania struktury docelowej zestawu. Po załadowaniu zestawu kliknij katalog główny węzła zestawu i możesz znaleźć informacje w deklaracji TargetFramework:

[assembly: TargetFramework(".NETFramework,Version=v4.5", FrameworkDisplayName = ".NET Framework 4.5")]
tsandhol
źródło
2
Należy pamiętać, że TargetFrameworkAttribute został dodany tylko w .NET 4.0, więc nie będzie obecny w zestawach skompilowanych dla .NET 3.5 lub wcześniejszych.
Wai Ha Lee
ILSpy pokazuje „Runtime: vXXX” w komentarzach po kliknięciu załadowanego węzła głównego zespołu. Udało mi się zobaczyć projekt ramowy v1.1.4322.
ryancdotnet
15

Z kodu, którego możesz użyć, Assembly.ImageRuntimeVersionale patrząc na plik prawdopodobnie najlepiej byłoby użyć reflektora i sprawdzić, do której wersji mscorlibsię odwołujesz.

Edycja: jeszcze lepiej byłoby użyć ildasm , otworzyć zestaw, a następnie wyświetlić manifest zestawu. Pierwszy wiersz manifestu zawiera dokładną wersję środowiska CLR, dla którego został zbudowany zestaw.

Andrew Hare
źródło
3
To jest źle. OP zapytał o wersję .NET Framework, a nie o wersję środowiska wykonawczego CLR. Ta odpowiedź dotyczy tego drugiego. Na przykład korzystam z Framework 4.7.2531.0, który używa CLR Runtime w wersji 4.0.30139. ImageRuntimeVersion zwraca wersję CLR, a nie wersję Framework.
Tom Baxter
11

Możesz użyć narzędzia o nazwie CorFlags.exe. Jest już od .NET 2.0 i wiem na pewno, że jest zawarty w Windows SDK 7.0. Domyślnie (w systemie Windows XP Pro) jest instalowany w C: \ Program Files \ Microsoft SDKs \ Windows \ v7.0A \ bin \ CorFlags.exe. Podaj mu ścieżkę do pliku zarządzanego modułu (bez żadnych innych flag wiersza polecenia), aby wyświetlić jego informacje nagłówkowe, w tym wersję.

Należy pamiętać, że to narzędzie jest przeznaczone do modyfikowania nagłówka PE32 modułu, więc nie używaj żadnej z flag, dopóki dokładnie nie przeczytasz dokumentacji .

Vince Fedorchak
źródło
2
Nie można rozróżnić między .Net4 i .Net4.5
mheyman
11

Z wiersza poleceń: find "Framework" MyApp.exe

Sean B.
źródło
2

Możesz też po prostu dowiedzieć się, jakie odniesienie do System.Core ma. Dzięki temu dowiesz się, z jakiej wersji .NET Framework korzysta ta aplikacja. W przypadku wersji 2.0 wersja System.Core to 2.0.xxx.xxx. W przypadku wersji 3.5 będzie to 3.5.xxx.xxx itd.

Denis
źródło
Nie sądzę, żeby to była prawda. Mam docelowy framework 4.5, ale używam System.Core 4.0.XXX.XXX
Paul Totzke
2

Wersję .NET pliku można uzyskać w systemie Windows za pomocą programu PowerShell. Poniższy skrypt;

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

daje następujący wynik; wprowadź opis obrazu tutaj

Zauważ, że wynik wyodrębnił wersję .NET dla plików exe w tym folderze, ale zrobi to również dla dll.

Mark Walker
źródło
1

W systemie Linux / OSX / unix możesz użyć:

strings that_app.exe | grep 'v2.\|Framework'
Pierz
źródło