2009-10-19 5 views
30

Что является самым простым способом обнаружения (без доступа к исходному проекту), была ли сборка .NET-сборки DLL компиляцией «x86», «x64», или «Любой процессор»?Как рассказать, была ли сборка .NET собрана как x86, x64 или любой CPU

Обновление: Утилита командной строки была достаточной для удовлетворения моих непосредственных потребностей, но только ради полноты, если кто-то хочет сказать мне, как это сделать программно, тогда это тоже будет интересно, я уверен ,

+0

Я бы рекомендовал искать через ISA для x86 и x64 и генерировать множество различных инструкций между ними. Затем я буду искать двоичные файлы dll для этих различий и (надеюсь), которые дадут вам результат, который вы хотите. Даже в этом случае это звучит сложно, склонный к ошибкам, и я бы не рекомендовал его. (Я не знаю, содержит ли DLL эту информацию) –

+0

Вы ищете инструмент или как это сделать программно? – pbz

+0

В идеале щелкните правой кнопкой мыши/свойства/детали, но, увы :( –

ответ

45

Если вы просто хотите, чтобы найти это на данной DLL, то вы можете использовать CorFlags инструмент, который является частью Windows SDK:

CorFlags.exe assembly.dll 

Если вы хотите сделать это с помощью кода , посмотрите на GetPEKind способе Module класса:

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

затем нужно изучить peKind проверить его значение. См. MSDN docs для PortableExecutableKinds для получения дополнительной информации.

+0

Спасибо Я запускал 'CorFlags.exe', но я не понимаю, как читать вывод. Что бы я увидел, это сборка x86/x64/AnyCPU? –

+1

@ColonelPanic: Ищите флаг' 32BIT'. Если это '1 ', то сборка компилируется только для 32-разрядных. – adrianbanks

+0

Я устанавливаю VS 2008, VS 2010, VS 2012 и VS 2013. У меня есть 8 файлов CorFlags.exe в подпапках в C: \ Program Files (x86) \ Microsoft SDK \ Windows \ .Какой я должен использовать? – Kiquenet

13

Thanks Adrian! Я переписал фрагмент в PowerShell, чтобы использовать его на сервере.

#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

Удивительный. Я бы дал ему +2, если бы мог – JMarsch

2

Спасибо Адриан и Питер! Вот модифицированная версия Get-Bitness от Peter, которая 1) берет список файлов для проверки из конвейера и 2) не умирает, если смотрит на не-NET 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 
     } 
    } 
} 

Я новичок в PowerShell, поэтому это не может быть примером лучших практик.

В качестве альтернативы, в соответствии с https://stackoverflow.com/a/4719567/64257 может также быть полезным командлет Get-PEHeader в PowerShell Community Extensions.

3

C# сниппет, на основе ответов 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();