Как определить, была ли сборка .NET построена для x86 или x64?
У меня есть произвольный список сборников .NET.
Мне нужно программно проверить, была ли построена каждая DLL для x86 (в отличие от x64 или Any CPU). Возможно ли это?
Ответы
Ответ 1
Посмотрите 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 в этом примере для вызова метода.
Ответ 2
Вы можете использовать инструмент CorFlags CLI (для экземпляр, C:\Program Files\Microsoft SDK\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
(любой процессор) вместе с другими атрибутами.
Ответ 3
Для уточнения, CorFlags.exe является частью .NET Framework SDK. У меня есть инструменты для разработки на моей машине, и самый простой способ для меня определить, является ли DLL 32-разрядной только:
-
Откройте командную строку Visual Studio (в меню Windows: меню "Пуск/Программы/Microsoft Visual Studio/Visual Studio Tools/Visual Studio 2008" )
-
CD в каталог, содержащий соответствующую DLL
-
Запуск таких флагов:
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
Ответ 4
Как насчет того, что вы просто пишете себя? Ядро архитектуры PE не было серьезно изменено с момента его внедрения в Windows 95. Здесь пример С#:
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.
Но с помощью этого метода он позволяет использовать возможности новых констант, просто подтвердите возврат, как вы сочтете нужным.
Ответ 5
Попробуйте использовать CorFlagsReader из этого проекта в CodePlex. Он не имеет ссылок на другие сборки и может использоваться как есть.
Ответ 6
[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);
}
}
Ответ 7
Ниже приведен командный файл, который будет запускать corflags.exe
для всех dlls
и exes
в текущем рабочем каталоге и во всех подкаталогах, анализировать результаты и отображать целевую архитектуру каждого из них.
В зависимости от используемой версии corflags.exe
позиции на выходе будут либо включать 32BIT
, либо 32BITREQ
(и 32BITPREF
). Какой бы ни был из этих двух включенных в вывод, это критическая позиция, которую необходимо проверить, чтобы различать Any CPU
и x86
. Если вы используете старую версию corflags.exe
(pre 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.
Ответ 8
Еще один способ проверить целевую платформу сборки .NET - это проверить сборку с помощью .NET Reflector...
@# ~ # ~ €! Я только что понял, что новая версия не бесплатна! Итак, исправление, если у вас есть свободная версия рефлектора .NET, вы можете использовать его для проверки целевой платформы.
Ответ 9
cfeduke отмечает возможность вызова GetPEKind. Это потенциально интересно сделать это от PowerShell.
Здесь, например, это код для командлета, который можно использовать: fooobar.com/questions/18062/...
В качестве альтернативы, в fooobar.com/questions/18064/... отмечается, что "там также командлет Get-PEHeader в Расширения сообщества PowerShell, которые можно использовать для проверки исполняемых изображений."
Ответ 10
Более продвинутое приложение для этого можно найти здесь: 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
Ответ 11
Еще один способ - использовать 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 OD THE DLL>
Ответ 12
DotPeek от JetBrians обеспечивает быстрый и простой способ увидеть msil (anycpu), x86, x64
![dotPeek]()