2009-10-19 4 views
30

Jaki jest najłatwiejszy sposób odkrycia (bez dostępu do projektu źródłowego), czy biblioteka DLL zestawu .NET została skompilowana jako "x86", "x64" lub "Any CPU"?Jak ustalić, czy zestaw .NET został skompilowany jako x86, x64 lub dowolny procesor

Aktualizacja: Narzędzie wiersza poleceń było wystarczające do zaspokojenia moich bezpośrednich potrzeb, ale tylko ze względu na kompletność, jeśli ktoś chce mi powiedzieć, jak to zrobić programowo, to też byłoby to interesujące, jestem pewien, że .

+0

Polecam przeszukując ISA dla x86 i x64 i wygenerować zbiór różnych instrukcji między nimi. Następnie przeszukałbym pliki binarne dll dla tych różnic i (miejmy nadzieję), który daje wynik, który chcesz. Mimo to brzmi to trudniej, jest podatne na błędy i nie polecam go. (Nie wiem, czy biblioteka DLL sama zawiera te informacje) –

+0

Czy szukasz narzędzia lub jak to zrobić programowo? – pbz

+0

Idealnie, kliknij prawym przyciskiem myszy/właściwości/szczegóły, ale niestety :( –

Odpowiedz

45

Jeśli chcesz tylko znaleźć na to uwagę w danej bibliotece DLL, można użyć narzędzia CorFlags który jest częścią Windows SDK:

CorFlags.exe assembly.dll 

Jeśli chcesz to zrobić za pomocą kodu , spojrzeć na metody klasy ModuleGetPEKind:

Assembly assembly = Assembly.LoadFrom("path to dll"); 
PortableExecutableKinds peKind; 
ImageFileMachine imageFileMachine; 
assembly.ManifestModule.GetPEKind(out peKind, out imageFileMachine) 

następnie należy zbadać peKind sprawdzić jego wartość. Aby uzyskać więcej informacji, zobacz MSDN docs dla PortableExecutableKinds.

+0

Dzięki Uruchomiłem 'CorFlags.exe', ale nie rozumiem, jak odczytać dane wyjściowe.Jak zobaczyłabym zespół x86/x64/AnyCPU? –

+1

@ColonelPanic: Poszukaj flagi' 32BIT' .Jeśli jest to '1 ', a następnie zestaw jest kompilowany tylko dla wersji 32. – adrianbanks

+0

Instaluję VS 2008, VS 2010, VS 2012 i VS 2013. Mam 8 plików CorFlags.exe w podfolderach w C: \ Program Files (x86) \ Microsoft SDKs \ Windows \. Którego powinienem użyć? – Kiquenet

13

Dzięki Adrian! Odtworzono fragment kodu w PowerShell, więc mogłem go użyć na serwerze.

#USAGE #1 
# Get-Bitness (dir *.dll | select -first 1) 
#USAGE #2 
# Get-Bitness "C:\vs\projects\bestprojectever\bin\debug\mysweetproj.dll" 
function Get-Bitness([System.IO.FileInfo]$assemblyFile) 
{ 
    $peKinds = new-object Reflection.PortableExecutableKinds 
    $imageFileMachine = new-object Reflection.ImageFileMachine 
    $a = [Reflection.Assembly]::LoadFile($assemblyFile.Fullname) 
    $a.ManifestModule.GetPEKind([ref]$peKinds, [ref]$imageFileMachine) 

    return $peKinds 
} 
+0

Awesome. Dałbym +2, gdybym mógł – JMarsch

2

Dzięki Adrian i Peter! Oto zmodyfikowana wersja Get-Bitness Petera, która 1) pobiera listę plików do sprawdzenia z potoku i 2) nie umiera, jeśli patrzy na bibliotekę DLL inną niż .NET (np. Jeśli patrzy na pewne biblioteki DLL C++) :

# example usage: dir *.exe,*.dll | Get-PEKind 
function Get-PEKind { 
    Param(
     [Parameter(Mandatory=$True,ValueFromPipeline=$True)] 
     [System.IO.FileInfo]$assemblies 
    ) 

    Process { 
     foreach ($assembly in $assemblies) { 
      $peKinds = new-object Reflection.PortableExecutableKinds 
      $imageFileMachine = new-object Reflection.ImageFileMachine 
      try 
      { 
       $a = [Reflection.Assembly]::LoadFile($assembly.Fullname) 
       $a.ManifestModule.GetPEKind([ref]$peKinds, [ref]$imageFileMachine) 
      } 
      catch [System.BadImageFormatException] 
      { 
       $peKinds = [System.Reflection.PortableExecutableKinds]"NotAPortableExecutableImage" 
      } 

      $o = New-Object System.Object 
      $o | Add-Member -type NoteProperty -name File -value $assembly 
      $o | Add-Member -type NoteProperty -name PEKind -value $peKinds 
      Write-Output $o 
     } 
    } 
} 

Jestem nowy w PowerShell, więc może to nie być przykład najlepszych praktyk.

Alternatywnie, zgodnie z https://stackoverflow.com/a/4719567/64257 może być również przydatny cmdlet Get-PEHeader w PowerShell Community Extensions.

3

urywek C#, oparte na odpowiedziach PowerShell:

var modules = assembly.GetModules(); 
var kinds = new List<PortableExecutableKinds>(); 
var images = new List<ImageFileMachine>(); 
foreach (var module in modules) 
{ 
    PortableExecutableKinds peKinds; 
    ImageFileMachine imageFileMachine; 
    module.GetPEKind(out peKinds, out imageFileMachine); 

    kinds.Add(peKinds); 
    images.Add(imageFileMachine); 
} 

var distinctKinds = kinds.Distinct().ToList(); 
var distinctImages = images.Distinct().ToList();