2008-11-06 3 views
269

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

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

+0

Возможный дубликат [Как определить, для какой платформы скомпилирован исполняемый файл?] (http://stackoverflow.com/questions/197951/how-can-i-determine-for-which- platform-an-executable-is-compiled) – nawfal 2013-02-25 19:26:32

+2

Вы также можете проверить это: [check-if-unmanaged-dll-is-32-bit-or-64-bit] (http://stackoverflow.com/вопросы/1001404/проверить, если-неуправляемый-DLL-это-32-битовый или 64-бит). – Matt 2015-05-11 10:16:08

+2

В более поздней версии CorFlags, соответствующей .NET 4.5, [«32BIT» был заменен на «32BITREQ» и «32BITPREF».] (Http://stackoverflow.com/questions/18608785/how-to-interpret-the- CorFlags-флаги/23614024 # 23614024). – 2015-06-28 13:35:05

ответ

213

Посмотрите на 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/... 
ProcessorArchitecture : MSIL 
Flags     : PublicKey 
HashAlgorithm   : SHA1 
VersionCompatibility : SameMachine 
KeyPair    : 
FullName    : Microsoft.GLEE, Version=1.0.0.0, Culture=neut... 

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

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

202

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

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

Сообщение в блоге x64 Development with .NET имеет некоторую информацию о corflags.

Еще лучше, если вы можете use Module.GetPEKind, чтобы определить, сборка, является ли значение PortableExecutableKindsPE32Plus (64-бит), Required32Bit (32-битные и ВАУ), или ILOnly (любой процессор) вместе с другими атрибутами.

+1

После просмотра вашего обновления, использование GetPEKind, похоже, является правильным способом для этого. Я отметил ваш ответ. – 2008-11-07 05:38:12

+0

Отличный отзыв о Module.GetPEKind, никогда не знал об этом до сих пор. Я всегда использовал инструмент `corflags`. – 2009-08-15 13:42:45

+8

GetPEKind не работает в 64-битном процессе при проверке 32-битных сборок – jjxtra 2010-04-19 16:25:55

125

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

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

  2. CD в папку, содержащую DLL в вопросе

  3. Run 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 

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

  • Любой CPU: PE = PE32 и 32bit = 0
  • x86: PE = PE32 и 32BIT = 1
  • 64-бит: PE = PE32 + и 32BIT = 0
1

Другой способ проверить целевую платформу сборки .NET инспектирует сборку с .NET Reflector ...

@ # ~ # ~ €! Я только что понял, что новая версия не бесплатна! Итак, исправление, если у вас есть свободная версия рефлектора .NET, вы можете использовать его для проверки целевой платформы.

17

Как насчет того, что вы просто пишете себя? Ядро архитектуры 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

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

1

cfeduke отмечает возможность вызова GetPEKind. Это потенциально интересно сделать это от PowerShell.

Вот, к примеру, код командлетов, которые могут быть использованы: https://stackoverflow.com/a/16181743/64257

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

5
[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); 
    } 
} 
3

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

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

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

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

corflags : error CF008 : The specified file does not have a valid managed header

@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. 
1

Более продвинутое приложение для этого вы можете найти здесь: CodePlex - ApiChange

Примеры:

C:\Downloads\ApiChange>ApiChange.exe -CorFlags c:\Windows\winhlp32.exe 
File Name; Type; Size; Processor; IL Only; Signed 
winhlp32.exe; Unmanaged; 296960; X86 

C:\Downloads\ApiChange>ApiChange.exe -CorFlags c:\Windows\HelpPane.exe 
File Name; Type; Size; Processor; IL Only; Signed 
HelpPane.exe; Unmanaged; 733696; Amd64 
1

Еще один способ будет использовать 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 

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

более полезным вариант с dumpbin.exe является/ЭКСПОРТ, Он покажет вам функцию открытой в библиотеке DLL

dumpbin.exe /EXPORTS <PATH OD THE DLL> 
2

DotPeek от JetBrians обеспечивает быстрый и легкий способ увидеть MSIL (AnyCPU), x86, x64 dotPeek

Смежные вопросы