Jak mogę 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?

Author: Peter Mortensen, 2008-11-06

15 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ę.

  • Amd64-64-bitowy procesor oparty na architekturze x64.
  • Arm : Procesor ARM.
  • Ia64: 64-bitowy procesor Intel Itanium.
  • MSIL : neutralne w odniesieniu do procesora i bity na słowo.
  • X86-32-bitowy procesor Intela, natywny lub w środowisku Windows on Windows na platformie 64-bitowej (WOW64).
  • None : nieznana lub nieokreślona kombinacja procesora i bitów na słowo.

Używam PowerShell w tym przykładzie do wywołania metody.

 298
Author: x0n,
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-10-30 18:48:34

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.

 225
Author: cfeduke,
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:

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

  2. CD do katalogu zawierającego daną bibliotekę DLL

  3. 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
 143
Author: JoshL,
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
2019-10-27 08:32:35

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.

 22
Author: Jason,
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.

 9
Author: Ludwo,
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

DotPeek z JetBrains zapewnia szybki i łatwy sposób na zobaczenie msil (anycpu), x86, x64 dotPeek

 8
Author: Prabhakaran Rajagopal,
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
2020-09-04 15:37:48
[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);
    }
}
 6
Author: Morgan Mellor,
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.
 5
Author: Eric Lease,
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

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>
 2
Author: Ayush joshi,
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

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

 2
Author: BlackGad,
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

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

Tutaj wpisz opis obrazka

 2
Author: thalm,
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

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.

 1
Author: sakito,
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."

 1
Author: Chris,
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
 1
Author: Wernfried Domscheit,
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

Alternatywą dla już wymienionych narzędzi jest Telerik JustDecompile (darmowe narzędzie), które wyświetli informacje obok nazwy zestawu:

Dowolne lub x86 lub x64 informacje w Telerik

 0
Author: Alexei - check Codidact,
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
2020-05-19 11:30:02