Как определить, была ли сборка .NET построена для x86 или x64? - PullRequest
300 голосов
/ 07 ноября 2008

У меня есть произвольный список сборок .NET.

Мне нужно программно проверить, была ли каждая DLL создана для x86 (в отличие от x64 или любого процессора). Это возможно?

Ответы [ 14 ]

256 голосов
/ 07 ноября 2008

Посмотрите на System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)

Вы можете просмотреть метаданные сборки из возвращенного экземпляра AssemblyName:

Использование PowerShell :

[36] C:\> [reflection.assemblyname]::GetAssemblyName("${pwd}\Microsoft.GLEE.dll") | fl

Name                  : Microsoft.GLEE
Version               : 1.0.0.0
CultureInfo           :
CodeBase              : file:///C:/projects/powershell/BuildAnalyzer/...
EscapedCodeBase       : file:///C:/projects/powershell/BuildAnalyzer/...
<b>ProcessorArchitecture : MSIL</b>
Flags                 : PublicKey
HashAlgorithm         : SHA1
VersionCompatibility  : SameMachine
KeyPair               :
FullName              : Microsoft.GLEE, Version=1.0.0.0, Culture=neut... 

Здесь ProcessorArchitecture определяет целевую платформу.

  • Amd64 : 64-разрядный процессор на основе архитектуры x64.
  • Arm : процессор ARM.
  • IA64 : только для 64-разрядного процессора Intel Itanium.
  • MSIL : Нейтрально по отношению к процессору и битам на слово.
  • X86 : 32-разрядный процессор Intel, встроенный или в среде Windows на Windows, на 64-разрядной платформе (WOW64).
  • Нет : неизвестная или неопределенная комбинация процессора и битов на слово.

В этом примере я использую PowerShell для вызова метода.

216 голосов
/ 07 ноября 2008

Вы можете использовать инструмент CorFlags CLI (например, C: \ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Bin \ CorFlags.exe) для определения статус сборки, основанный на ее выводе и открытии сборки как бинарного актива, вы сможете определить, где вам нужно искать, чтобы установить, установлен ли флаг 32BIT в 1 ( x86 ) или 0 ( Любой процессор или x64 , в зависимости от PE):

Option    | PE    | 32BIT
----------|-------|---------
x86       | PE32  | 1
Any CPU   | PE32  | 0
x64       | PE32+ | 0

В блоге x64 Разработка с использованием .NET содержит некоторую информацию о corflags.

Еще лучше, вы можете использовать Module.GetPEKind, чтобы определить, является ли сборка PortableExecutableKinds значением PE32Plus (64-бит), Required32Bit (32-бит и WOW) или ILOnly (любой ЦП) вместе с другими атрибутами.

135 голосов
/ 16 июня 2009

Только для пояснения, CorFlags.exe является частью .NET Framework SDK . У меня есть инструменты разработки на моей машине, и самый простой способ определить, является ли DLL 32-битной, это:

  1. Откройте командную строку Visual Studio (В Windows: меню Пуск / Программы / Microsoft Visual Studio / Инструменты Visual Studio / Командная строка Visual Studio 2008)

  2. CD к каталогу, содержащему данную DLL

  3. Запустите corflags, как это: corflags MyAssembly.dll

Вы получите что-то вроде этого:

    Microsoft (R) .NET Framework CorFlags Conversion Tool.  Version  3.5.21022.8
Copyright (c) Microsoft Corporation.  All rights reserved.

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 3
ILONLY    : 1
32BIT     : 1
Signed    : 0

В соответствии с комментариями вышеприведенные флаги следует читать следующим образом:

  • Любой процессор: PE = PE32 и 32BIT = 0
  • x86: PE = PE32 и 32BIT = 1
  • 64-бит: PE = PE32 + и 32BIT = 0
18 голосов
/ 19 марта 2012

Как насчет того, чтобы написать себе? Ядро архитектуры PE не претерпело серьезных изменений с момента ее реализации в Windows 95. Вот пример C #:

    public static ushort GetPEArchitecture(string pFilePath)
    {
        ushort architecture = 0;
        try
        {
            using (System.IO.FileStream fStream = new System.IO.FileStream(pFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
            {
                using (System.IO.BinaryReader bReader = new System.IO.BinaryReader(fStream))
                {
                    if (bReader.ReadUInt16() == 23117) //check the MZ signature
                    {
                        fStream.Seek(0x3A, System.IO.SeekOrigin.Current); //seek to e_lfanew.
                        fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin); //seek to the start of the NT header.
                        if (bReader.ReadUInt32() == 17744) //check the PE\0\0 signature.
                        {
                            fStream.Seek(20, System.IO.SeekOrigin.Current); //seek past the file header,
                            architecture = bReader.ReadUInt16(); //read the magic number of the optional header.
                        }
                    }
                }
            }
        }
        catch (Exception) { /* TODO: Any exception handling you want to do, personally I just take 0 as a sign of failure */}
        //if architecture returns 0, there has been an error.
        return architecture;
    }
}

Теперь текущие константы:

0x10B - PE32  format.
0x20B - PE32+ format.

Но с помощью этого метода он допускает возможности новых констант, просто проверяйте возвращаемость, как считаете нужным.

9 голосов
/ 18 февраля 2013

Попробуйте использовать CorFlagsReader из этого проекта на CodePlex . Он не имеет ссылок на другие сборки и может использоваться как есть.

6 голосов
/ 26 сентября 2013
[TestMethod]
public void EnsureKWLLibrariesAreAll64Bit()
{
    var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Where(x => x.FullName.StartsWith("YourCommonProjectName")).ToArray();
    foreach (var assembly in assemblies)
    {
        var myAssemblyName = AssemblyName.GetAssemblyName(assembly.FullName.Split(',')[0] + ".dll");
        Assert.AreEqual(ProcessorArchitecture.MSIL, myAssemblyName.ProcessorArchitecture);
    }
}
5 голосов
/ 22 августа 2017

DotPeek от JetBrians обеспечивает быстрый и простой способ просмотра msil (anycpu), x86, x64 dotPeek

4 голосов
/ 30 марта 2016

Ниже приведен пакетный файл, который будет запускаться corflags.exe для всех dlls и exes в текущем рабочем каталоге и во всех подкаталогах, анализировать результаты и отображать целевую архитектуру каждого из них.

В зависимости от используемой версии corflags.exe позиции в выходных данных будут включать 32BIT, или 32BITREQ32BITPREF). Независимо от того, что из этих двух включено в выходные данные, это критическая позиция, которую необходимо проверить, чтобы различить Any CPU и x86. Если вы используете более старую версию corflags.exe (до Windows SDK v8.0A), то в выводе будет присутствовать только позиция 32BIT, как другие указывали в предыдущих ответах. В противном случае 32BITREQ и 32BITPREF замените его.

Предполагается, что corflags.exe находится в %PATH%. Самый простой способ убедиться в этом - использовать Developer Command Prompt. В качестве альтернативы вы можете скопировать его из местоположения по умолчанию .

Если приведенный ниже пакетный файл запущен для неуправляемого dll или exe, он будет некорректно отображаться как x86, поскольку фактический вывод Corflags.exe будет сообщением об ошибке, похожим на:

corflags: ошибка CF008: указанный файл не имеет действительного управляемого заголовка

@echo off

echo.
echo Target architecture for all exes and dlls:
echo.

REM For each exe and dll in this directory and all subdirectories...
for %%a in (.exe, .dll) do forfiles /s /m *%%a /c "cmd /c echo @relpath" > testfiles.txt

for /f %%b in (testfiles.txt) do (
    REM Dump corflags results to a text file
    corflags /nologo %%b > corflagsdeets.txt

   REM Parse the corflags results to look for key markers   
   findstr /C:"PE32+">nul .\corflagsdeets.txt && (      
      REM `PE32+` indicates x64
        echo %%~b = x64
    ) || (
      REM pre-v8 Windows SDK listed only "32BIT" line item, 
      REM newer versions list "32BITREQ" and "32BITPREF" line items
        findstr /C:"32BITREQ  : 0">nul /C:"32BIT     : 0" .\corflagsdeets.txt && (
            REM `PE32` and NOT 32bit required indicates Any CPU
            echo %%~b = Any CPU
        ) || (
            REM `PE32` and 32bit required indicates x86
            echo %%~b = x86
        )
    )

    del corflagsdeets.txt
)

del testfiles.txt
echo.
2 голосов
/ 18 августа 2018

Я клонировал очень удобный инструмент, который добавляет пункт контекстного меню для сборок в проводнике Windows, чтобы показать всю доступную информацию:

Скачать здесь: https://github.com/tebjan/AssemblyInformation/releases

enter image description here

2 голосов
/ 28 июля 2017

Еще одним способом было бы использовать dumpbin из инструментов Visual Studio для DLL и искать соответствующий вывод

dumpbin.exe /HEADERS <your dll path>
    FILE HEADER VALUE
                 14C machine (x86)
                   4 number of sections
            5885AC36 time date stamp Mon Jan 23 12:39:42 2017
                   0 file pointer to symbol table
                   0 number of symbols
                  E0 size of optional header
                2102 characteristics
                       Executable
                       32 bit word machine
                       DLL

Примечание: выше o / p для 32-битной DLL

Еще одна полезная опция для dumpbin.exe - / EXPORTS, она покажет вам функцию, предоставляемую dll

dumpbin.exe /EXPORTS <PATH OF THE DLL>
...