Jak ustalić, czy a.NET montaż został zbudowany dla x86 lub x64?
Mam dowolną listę zestawów. NET.
Muszę programowo sprawdzić, czy każdy DLL został zbudowany dla x86(w przeciwieństwie do X64 lub dowolnego procesora). Czy to możliwe?
14 answers
Spójrz na System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)
Możesz sprawdzić metadane złożenia ze zwracanej instancji AssemblyName:
Using 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...
Tutaj, Procesoraarchitektura identyfikuje docelową platformę.
Używam PowerShell w tym przykładzie do wywołania metody.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-28 10:08:10
Możesz użyć CorFlags CLI narzędzie (na przykład, C:\Program Files\Microsoft SDKs \ Windows \ v7. 0 \ Bin\CorFlags.exe) aby określić status złożenia, na podstawie jego wyjścia i otwarcia złożenia jako zasobu binarnego, powinieneś być w stanie określić, gdzie należy szukać, aby określić, czy znacznik 32-bitowy jest ustawiony na 1 (x86) lub 0 ( dowolny procesor lub x64 , w zależności od PE
):
Option | PE | 32BIT
----------|-------|---------
x86 | PE32 | 1
Any CPU | PE32 | 0
x64 | PE32+ | 0
Wpis na blogu rozwój x64 z . NET posiada pewne informacje o corflags
.
Jeszcze lepiej, możesz użyć Module.GetPEKind
aby określić, czy zbiór jest PortableExecutableKinds
wartością PE32Plus
(64-bitowy), Required32Bit
(32-bit i WOW), lub ILOnly
(dowolny procesor) wraz z innymi atrybutami.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-28 13:24:55
Dla wyjaśnienia, CorFlags.exe jest częścią . NET Framework SDK . Mam narzędzia programistyczne na swojej maszynie i najprostszym sposobem dla mnie określić, czy DLL jest tylko 32-bitowy jest:
Otwórz wiersz polecenia programu Visual Studio (w systemie Windows: menu Start/Programy/Microsoft Visual Studio/narzędzia Visual Studio/Wiersz polecenia programu Visual Studio 2008)
-
CD do katalogu zawierającego daną bibliotekę DLL
Uruchom corflags jak to:
corflags MyAssembly.dll
Otrzymasz wyjście coś takiego:
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
Zgodnie z komentarzami powyższe flagi należy odczytywać w następujący sposób:
- dowolny procesor: PE = PE32 i 32bit = 0
- x86: PE = PE32 i 32BIT = 1
- 64-bit: PE = PE32+ i 32bit = 0
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-15 08:18:11
Może po prostu napiszesz swoje? Rdzeń architektury PE nie został poważnie zmieniony od czasu jego implementacji w systemie Windows 95. Oto przykład 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;
}
}
Teraz obecne stałe to:
0x10B - PE32 format.
0x20B - PE32+ format.
Ale dzięki tej metodzie pozwala na możliwości nowych stałych, wystarczy zweryfikować zwrot według własnego uznania.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-19 09:31:37
Spróbuj użyć CorFlagsReader z tego projektu w CodePlex. Nie ma odniesień do innych zespołów i może być używany tak, jak jest.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-18 12:45:49
[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);
}
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-09-26 18:24:20
Poniżej znajduje się plik wsadowy, który uruchomi corflags.exe
przeciwko wszystkim dlls
i exes
w bieżącym katalogu roboczym i wszystkich podkatalogach, przeanalizuje wyniki i wyświetli docelową architekturę każdego z nich.
W zależności od wersji corflags.exe
, która jest używana, pozycje linii w wyjściu będą zawierać 32BIT
, lub 32BITREQ
(i 32BITPREF
). Którakolwiek z tych dwóch pozycji jest elementem krytycznym linii, który należy sprawdzić, aby odróżnić Any CPU
i x86
. Jeśli jeśli używasz starszej wersji corflags.exe
(pre Windows SDK v8.0a), wtedy tylko pozycja linii 32BIT
będzie obecna na wyjściu, tak jak inni wskazywali w poprzednich odpowiedziach. W przeciwnym razie 32BITREQ
i 32BITPREF
zastąp go.
Zakłada się, że corflags.exe
jest w %PATH%
. Najprostszym sposobem zapewnienia tego jest użycie Developer Command Prompt
. Alternatywnie możesz skopiować go z domyślnej lokalizacji .
Jeśli poniższy plik wsadowy zostanie uruchomiony z niezarządzanym dll
lub exe
, zostanie nieprawidłowo wyświetlony jako x86
, ponieważ rzeczywisty wynik z Corflags.exe
będzie Komunikatem o błędzie podobnym do:
Corflags: błąd CF008: podany plik nie ma poprawnego zarządzanego nagłówka
@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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:17
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-08-22 07:20:43
Innym sposobem sprawdzenia docelowej platformy zestawu.NET jest sprawdzenie zestawu za pomocą . Net Reflektor...
@#~#€~! Właśnie zdałem sobie sprawę, że nowa wersja nie jest darmowa! Poprawka, jeśli masz darmową wersję. NET reflector, możesz jej użyć do sprawdzenia docelowej platformy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-14 09:30:10
Cfeduke zauważa możliwość wywołania GetPEKind. To potencjalnie interesujące zrobić to z PowerShell.
Tutaj, na przykład, jest kod dla cmdlet, który może być użyty: https://stackoverflow.com/a/16181743/64257
Https://stackoverflow.com/a/4719567/64257 zauważono, że " w rozszerzeniach PowerShell Community extensions PowerShell Community Extensions znajduje się również cmdlet Get-PEHeader, który może być użyty do testowania obrazów wykonywalnych."
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50
Bardziej zaawansowaną aplikację do tego można znaleźć tutaj: CodePlex-Apichange
Przykłady:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-10-04 12:12:36
Innym sposobem byłoby użycie dumpbin z narzędzi Visual Studio na DLL i poszukanie odpowiedniego wyjścia
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
Uwaga: powyżej o / p jest dla 32bit dll
Jeszcze jedna przydatna opcja z dumpbin.exe jest / eksportuje, pokaże Ci funkcję wystawioną przez dll
dumpbin.exe /EXPORTS <PATH OF THE DLL>
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-18 06:33:19
Sklonowałem bardzo poręczne narzędzie, które dodaje pozycję menu kontekstowego dla zespołów w Eksploratorze windows, aby wyświetlić wszystkie dostępne informacje:
Pobierz tutaj: https://github.com/tebjan/AssemblyInformation/releases
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-08-18 18:06:49
Bardziej ogólny sposób-użyj struktury pliku do określenia bitowości i typu obrazu:
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);
}
}
Wyliczenie trybu kompilacji
[Flags]
public enum CompilationMode
{
Invalid = 0,
Native = 0x1,
CLR = Native << 1,
Bit32 = CLR << 1,
Bit64 = Bit32 << 1
}
Kod źródłowy z wyjaśnieniem na GitHub
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-03-27 15:27:38