14 ответов:
посмотреть
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 в этом примере для вызова метода.
можно использовать CorFlagsCLI инструмент (например, C:\Program файлы\Microsoft SDKs\Windows\v7.0\Bin\CorFlags.exe) чтобы определить состояние сборки, основываясь на ее выводе и открытии сборки в качестве двоичного актива, вы должны быть в состоянии определить, где вам нужно искать, чтобы определить, установлен ли 32-битный флаг на 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 Command Prompt)
CD в каталог, содержащий DLL в вопрос
запустить 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
Как насчет того, чтобы написать свою собственную? Ядро архитектуры 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 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(предварительно 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 reflector, вы можете использовать ее для проверки целевой платформы.
cfeduke отмечает возможность вызова GetPEKind. Это потенциально интересно сделать из PowerShell.
вот, например, код командлета, который можно использовать:https://stackoverflow.com/a/16181743/64257
альтернативно, в https://stackoverflow.com/a/4719567/64257 отмечается, что " есть также командлет 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 tools на 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 для 32bit dll
еще один полезный вариант с dumpbin.exe is / EXPORTS, он покажет вам функцию, представленную dll
dumpbin.exe /EXPORTS <PATH OF THE DLL>
я клонировал супер удобный инструмент, который добавляет запись контекстного меню для сборок в проводнике windows, чтобы показать всю доступную информацию:
скачать здесь: https://github.com/tebjan/AssemblyInformation/releases
более общий способ-используйте файловую структуру для определения разрядности и типа изображения:
public static CompilationMode GetCompilationMode(this FileInfo info) { if (!info.Exists) throw new ArgumentException($"{info.FullName} does not exist"); var intPtr = IntPtr.Zero; try { uint unmanagedBufferSize = 4096; intPtr = Marshal.AllocHGlobal((int)unmanagedBufferSize); using (var stream = File.Open(info.FullName, FileMode.Open, FileAccess.Read)) { var bytes = new byte[unmanagedBufferSize]; stream.Read(bytes, 0, bytes.Length); Marshal.Copy(bytes, 0, intPtr, bytes.Length); } //Check DOS header magic number if (Marshal.ReadInt16(intPtr) != 0x5a4d) return CompilationMode.Invalid; // This will get the address for the WinNT header var ntHeaderAddressOffset = Marshal.ReadInt32(intPtr + 60); // Check WinNT header signature var signature = Marshal.ReadInt32(intPtr + ntHeaderAddressOffset); if (signature != 0x4550) return CompilationMode.Invalid; //Determine file bitness by reading magic from IMAGE_OPTIONAL_HEADER var magic = Marshal.ReadInt16(intPtr + ntHeaderAddressOffset + 24); var result = CompilationMode.Invalid; uint clrHeaderSize; if (magic == 0x10b) { clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 208 + 4); result |= CompilationMode.Bit32; } else if (magic == 0x20b) { clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 224 + 4); result |= CompilationMode.Bit64; } else return CompilationMode.Invalid; result |= clrHeaderSize != 0 ? CompilationMode.CLR : CompilationMode.Native; return result; } finally { if (intPtr != IntPtr.Zero) Marshal.FreeHGlobal(intPtr); } }перечисление режима компиляции
[Flags] public enum CompilationMode { Invalid = 0, Native = 0x1, CLR = Native << 1, Bit32 = CLR << 1, Bit64 = Bit32 << 1 }исходный код с объяснением в GitHub


Comments