У меня есть произвольный список сборников .NET.
Мне нужно программно проверить, была ли построена каждая DLL для x86 (в отличие от x64 или Any CPU). Возможно ли это?
У меня есть произвольный список сборников .NET.
Мне нужно программно проверить, была ли построена каждая DLL для x86 (в отличие от x64 или Any CPU). Возможно ли это?
Посмотрите 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 в этом примере для вызова метода.
Вы можете использовать инструмент 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
(любой процессор) вместе с другими атрибутами.
Для уточнения, 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 не было серьезно изменено с момента его внедрения в 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.
Но с помощью этого метода он позволяет использовать возможности новых констант, просто подтвердите возврат, как вы сочтете нужным.
Попробуйте использовать CorFlagsReader из этого проекта в CodePlex. Он не имеет ссылок на другие сборки и может использоваться как есть.
[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);
}
}
Ниже приведен командный файл, который будет запускать 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.
Еще один способ проверить целевую платформу сборки .NET - это проверить сборку с помощью .NET Reflector...
@# ~ # ~ €! Я только что понял, что новая версия не бесплатна! Итак, исправление, если у вас есть свободная версия рефлектора .NET, вы можете использовать его для проверки целевой платформы.
cfeduke отмечает возможность вызова GetPEKind. Это потенциально интересно сделать это от PowerShell.
Здесь, например, это код для командлета, который можно использовать: fooobar.com/questions/18062/...
В качестве альтернативы, в fooobar.com/questions/18064/... отмечается, что "там также командлет Get-PEHeader в Расширения сообщества PowerShell, которые можно использовать для проверки исполняемых изображений."
Более продвинутое приложение для этого можно найти здесь: 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
Еще один способ - использовать 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>
DotPeek от JetBrians обеспечивает быстрый и простой способ увидеть msil (anycpu), x86, x64