¿Cómo puedo determinar si un ensamblado .NET se creó para x86 o x64?

Resuelto Judah Gabriel Himango asked hace 16 años • 16 respuestas

Tengo una lista arbitraria de ensamblados .NET.

Necesito verificar mediante programación si cada DLL se creó para x86 (a diferencia de x64 o cualquier CPU). es posible?

Judah Gabriel Himango avatar Nov 07 '08 05:11 Judah Gabriel Himango
Aceptado

Mira a System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile).

Puede examinar los metadatos del ensamblado de la instancia de AssemblyName devuelta:

Usando PowerShell :

[36] C:\> [reflection.assemblyname]::GetAssemblyName("${pwd}\Microsoft.GLEE.dll") | Florida

Nombre : Microsoft.GLEE
Versión: 1.0.0.0
Información cultural:
CodeBase: archivo:///C:/projects/powershell/BuildAnalyzer/...
EscapedCodeBase: archivo:///C:/projects/powershell/BuildAnalyzer/...
Arquitectura del procesador: MSIL
Banderas: clave pública
Algoritmo Hash: SHA1
Compatibilidad de versiones: Misma máquina
Par de claves :
Nombre completo: Microsoft.GLEE, Versión=1.0.0.0, Cultura=neut...

Aquí, ProcessorArchitecture identifica la plataforma de destino.

  • Amd64 : Un procesador de 64 bits basado en la arquitectura x64.
  • Arm : Un procesador ARM.
  • IA64 : procesador Intel Itanium de 64 bits únicamente.
  • MSIL : Neutral respecto al procesador y bits por palabra.
  • X86 : Un procesador Intel de 32 bits, ya sea nativo o en el entorno Windows sobre Windows en una plataforma de 64 bits ( WoW64 ).
  • Ninguno : combinación desconocida o no especificada de procesador y bits por palabra.

Estoy usando PowerShell en este ejemplo para llamar al método.

x0n avatar Nov 06 '2008 22:11 x0n

Puede utilizar la herramienta CLI de CorFlags (por ejemplo, C:\Program Files\Microsoft SDKs\Windows\v7.0\Bin\CorFlags.exe) para determinar el estado de un ensamblaje, en función de su salida y abrir un ensamblaje como activo binario, debería poder determinar dónde debe buscar para determinar si el indicador de 32 bits está configurado en 1 ( x86 ) o 0 ( cualquier CPU o x64 , dependiendo de ):PE

Option    | PE    | 32BIT
----------|-------|---------
x86       | PE32  | 1
Any CPU   | PE32  | 0
x64       | PE32+ | 0

La publicación del blog Desarrollo x64 con .NET tiene información sobre corflags.

Aún mejor, puede usarloModule.GetPEKind para determinar si un ensamblaje tiene PortableExecutableKindsvalor PE32Plus(64 bits), Required32Bit(32 bits y WoW ) o ILOnly(cualquier CPU) junto con otros atributos.

cfeduke avatar Nov 06 '2008 22:11 cfeduke

Solo como aclaración, CorFlags.exe es parte del SDK de .NET Framework . Tengo las herramientas de desarrollo en mi máquina y la forma más sencilla para mí de determinar si una DLL es solo de 32 bits es:

  1. Abra el símbolo del sistema de Visual Studio (en Windows: menú Inicio/Programas/Microsoft Visual Studio/Visual Studio Tools/Símbolo del sistema de Visual Studio 2008)

  2. CD al directorio que contiene la DLL en cuestión

  3. Ejecute corflags como este: corflags MyAssembly.dll

Obtendrá un resultado similar a este:

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

Según los comentarios, las banderas anteriores deben leerse de la siguiente manera:

  • Cualquier CPU: PE = PE32 y 32BIT = 0
  • x86: PE = PE32 y 32 BITS = 1
  • 64 bits: PE = PE32+ y 32 bits = 0
JoshL avatar Jun 16 '2009 17:06 JoshL

Simplemente escribe el tuyo. El núcleo de la arquitectura PE no ha cambiado seriamente desde su implementación en Windows 95 .

Aquí hay un ejemplo de 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))
                {
                    // Check the MZ signature
                    if (bReader.ReadUInt16() == 23117)
                    {
                        // Seek to e_lfanew.
                        fStream.Seek(0x3A, System.IO.SeekOrigin.Current);

                        // Seek to the start of the NT header.
                        fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin);

                        if (bReader.ReadUInt32() == 17744) // Check the PE\0\0 signature.
                        {
                            // Seek past the file header,
                            fStream.Seek(20, System.IO.SeekOrigin.Current);

                            // Read the magic number of the optional header.
                            architecture = bReader.ReadUInt16();
                        }
                    }
                }
            }
        }
        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;
    }
}

Ahora las constantes actuales son:

0x10B - PE32  format.
0x20B - PE32+ format.

Pero con este método se permiten las posibilidades de nuevas constantes. Simplemente valida la devolución como mejor te parezca.

Jason avatar Mar 19 '2012 09:03 Jason