Как определить, была ли сборка .NET скомпилирована как x86, x64 или какой-либо процессор

Как проще всего определить (без доступа к исходному проекту), была ли скомпилирована DLL сборки .NET как x86, x64 или Any CPU?

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


person Tim Long    schedule 19.10.2009    source источник
comment
Я бы рекомендовал поискать в ISA x86 и x64 и сгенерировать набор различных инструкций между ними. Затем я бы поискал в двоичных файлах dll эти различия и (надеюсь), что даст вам желаемый результат. Даже в этом случае это звучит сложно, подвержено ошибкам, и я бы не рекомендовал это. (Я не знаю, содержит ли сама dll эту информацию)   -  person Robert Massaioli    schedule 20.10.2009
comment
Вы ищете инструмент или как это сделать самостоятельно программно?   -  person pbz    schedule 20.10.2009
comment
В идеале щелкнуть правой кнопкой мыши / свойства / подробности, но увы :(   -  person Colonel Panic    schedule 13.11.2012
comment
возможный дубликат Как определить была ли сборка .NET для x86 или x64?   -  person Blorgbeard    schedule 16.11.2012
comment
Как файл .bat   -  person Eric Lease    schedule 30.03.2016


Ответы (4)


Если вы просто хотите узнать это в конкретной 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 для PortableExecutableKinds.

person adrianbanks    schedule 19.10.2009
comment
Спасибо. Я запустил CorFlags.exe, но не понимаю, как читать вывод. Что бы я увидел в сборке x86 / x64 / AnyCPU? - person Colonel Panic; 13.11.2012
comment
@ColonelPanic: Ищите флаг 32BIT. Если это 1, то сборка компилируется только для 32-битной версии. - person adrianbanks; 14.11.2012
comment
Я устанавливаю VS 2008, VS 2010, VS 2012 и VS 2013. У меня есть 8 файлов CorFlags.exe в подпапках в C: \ Program Files (x86) \ Microsoft SDKs \ Windows \. Что я должен использовать? - person Kiquenet; 25.03.2014
comment
@Kiquenet: Я бы использовал последнюю версию (то есть из папки с самым высоким номером версии). - person adrianbanks; 26.03.2014

Спасибо, Адриан! Я переписал фрагмент в 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
}
person Peter Seale    schedule 14.12.2009
comment
Потрясающий. Я бы дал +2, если бы мог - person JMarsch; 25.03.2011

Спасибо, Адриан и Питер! Вот модифицированная версия Get-Bitness Питера, которая 1) берет список файлов для проверки из конвейера и 2) не умирает, если смотрит на не-.NET DLL (например, если он смотрит на определенные C ++ DLL) :

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

person Chris    schedule 24.04.2013

Фрагмент кода 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();
person fiat    schedule 19.01.2014