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



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.


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ą, F3aż .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 .


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


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

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.


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 .


2
Nie można rozróżnić między .Net4 i .Net4.5
— mheyman


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.


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.


1

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

strings that_app.exe | grep 'v2.\|Framework'
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.