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


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.