Tengo una lista arbitraria de ensamblados .NET.¿Cómo determinar si se construyó un ensamblado .NET para x86 o x64?
Necesito comprobar programáticamente si cada DLL se construyó para x86 (a diferencia de x64 o cualquier CPU). es posible?
Tengo una lista arbitraria de ensamblados .NET.¿Cómo determinar si se construyó un ensamblado .NET para x86 o x64?
Necesito comprobar programáticamente si cada DLL se construyó para x86 (a diferencia de x64 o cualquier CPU). es posible?
Mira System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)
Puede examinar los metadatos de montaje de la instancia AssemblyName devuelto:
Usando 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...
Aquí, ProcessorArchitecture identifica plataforma de destino.
Estoy usando PowerShell en este ejemplo para llamar al método.
Perdona la pregunta estúpida, pero ¿qué te dice esto que es x86? –
El campo Arquitectura de procesador es una enumeración; en el ejemplo anterior, está configurado en MSIL, lo que significa "Neutral con respecto al procesador y bits por palabra". Otros valores incluyen X86, IA64, Amd64. Ver http://msdn.microsoft.com/en-us/library/system.reflection.processorarchitecture.aspx para más detalles. –
Recibo el siguiente error al intentar usar PowerShell: 'Llamada de excepción" GetAssemblyName "con" 1 "argumento (s):" No se pudo cargar el archivo o ensamblado '[DLLName] .dll' o una de sus dependencias. El sistema no puede encontrar el archivo especificado. "' (Sí, lo deletreé correctamente). – PeterX
Puede usar la herramienta CorFlagsCLI (por ejemplo, C: \ Archivos de programa \ Microsoft SDKs \ Windows \ v7.0 \ Bin \ CorFlags.exe) para determinar el estado de un ensamblaje, en función de su salida y apertura un conjunto como un activo binaria que debe ser capaz de determinar dónde tiene que tratar de determinar si el indicador 32BIT se establece en 1 (x 86) 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 x64 Development with .NET tiene alguna información sobre corflags
.
Aún mejor, puede use Module.GetPEKind
para determinar si un conjunto es PortableExecutableKinds
valor PE32Plus
(64 bits), Required32Bit
(32 bits y WOW), o ILOnly
(cualquier CPU), junto con otros atributos.
Después de ver su actualización, usar GetPEKind parece ser la forma correcta de hacerlo. He marcado el tuyo como la respuesta. –
Excelente consejo sobre Module.GetPEKind, nunca lo supimos hasta ahora. Siempre he usado la herramienta 'corflags'. –
GetPEKind falla en un proceso de 64 bits al verificar conjuntos de 32 bits – jjxtra
Solo para aclaración, CorFlags.exe es parte de .NET Framework SDK. Tengo las herramientas de desarrollo en mi máquina, y la forma más sencilla para mí determinar si un archivo DLL es sólo de 32 bits es:
Abra el Visual Studio de comandos (en Windows: menú Inicio/Programas/Microsoft visual Studio/visual Studio Tools/visual Studio 2008 Command Prompt)
CD en el directorio que contiene el archivo DLL en cuestión
corflags ejecuta de la siguiente: corflags MyAssembly.DLL
obtendrá algo salida como esta:
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
De acuerdo con los comentarios de las banderas más arriba se van a leer de la siguiente manera:
Incorrecto. 0 = Cualquier CPU, no 2 –
Esto parece haber cambiado mientras tanto; corflags ahora muestra '32BITREQ' y' 32BITPREF' en lugar de un único valor '32BIT'. –
Microsoft .NET 4.5 introdujo una nueva opción, Cualquier CPU de 32 bits Preferido. [Aquí] (http://stackoverflow.com/a/23614024/465053) son los detalles. – RBT
Otra forma de comprobar la plataforma de destino de un ensamblado de .NET está inspeccionando el conjunto con .NET Reflector ...
@ # ~ # ~ €! ¡Me acabo de dar cuenta de que la nueva versión no es gratis! Entonces, corrección, si tiene una versión gratuita de .NET reflector, puede usarla para verificar la plataforma de destino.
Utilice [ILSpy] (http://wiki.sharpdevelop.net/ILSpy.ashx), es una aplicación básica de código abierto que hace las mismas cosas que Reflector –
¿Qué tal si solo te escribes? El núcleo de la arquitectura PE no ha sido cambiado en serio desde su implementación en Windows 95. He aquí 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))
{
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;
}
}
Ahora las constantes actuales son:
0x10B - PE32 format.
0x20B - PE32+ format.
Sin embargo, con este método que permite para las posibilidades de nuevas constantes, simplemente valide la devolución como mejor le parezca.
Interesante, gracias por el código con la explicación. Module.GetPEKind es probablemente la ruta más fácil. Pero esto es útil para aprender. Gracias. –
Muy interesante, pero cuando tengo una aplicación compilada con Cualquier CPU, el resultado es 0x10B. Esto es incorrecto porque mi aplicación se ejecuta en un sistema x64. ¿Hay alguna otra bandera para verificar? – Samuel
GetPEArchitecture funciona para ensamblados compilados con .net 3.5, 4.0, 4.5 y 4.5.1? De todos modos, creo, Module.GetPEKind falla en un proceso de 64 bits cuando se comprueban ensamblajes de 32 bits. – Kiquenet
Intente utilizar CorFlagsReader from this project at CodePlex. No tiene referencias a otros ensambles y puede usarse tal cual.
Esta es la respuesta más precisa y útil. –
El enlace sigue funcionando a partir de este escrito, pero como CodePlex está a punto de cerrarse, sería bueno realizar la acción adecuada antes de que sea demasiado tarde. –
cfeduke toma nota de la posibilidad de llamar a GetPEKind. Es potencialmente interesante hacer esto desde PowerShell.
Aquí, por ejemplo, es el código para un cmdlet que podría ser utilizado: https://stackoverflow.com/a/16181743/64257
Como alternativa, al https://stackoverflow.com/a/4719567/64257 se señala que "también hay el cmdlet Get-PEHeader en el PowerShell Community Extensions que se puede utilizar para probar imágenes ejecutables ".
[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);
}
}
Gracias por esto, una de nuestras aplicaciones debe ser construida como x86, agregar una prueba de unidad asegura que las bibliotecas de compilación del servidor de compilación serán de 32 bits y evita que esos errores ocurran :) – Mido
A continuación se muestra un archivo por lotes que ejecutará corflags.exe
contra todos dlls
y exes
en el directorio de trabajo actual y todos los subdirectorios, analizar los resultados y mostrar la arquitectura de destino de cada uno.
Dependiendo de la versión de corflags.exe
que se utiliza, los elementos de línea en la salida, o bien incluir 32BIT
, o32BITREQ
(y 32BITPREF
). Cualquiera de estos dos incluidos en el resultado es la línea de pedido crítica que se debe marcar para diferenciar entre Any CPU
y x86
. Si está utilizando una versión anterior de corflags.exe
(anterior a Windows SDK v8.0A), solo la línea de pedido 32BIT
estará presente en la salida, como otros han indicado en las respuestas anteriores. De lo contrario, 32BITREQ
y 32BITPREF
reemplazarlo.
Esto supone que corflags.exe
está en el %PATH%
.La forma más sencilla de garantizar esto es usar un Developer Command Prompt
. Alternativamente, puede copiarlo de default location.
Si el archivo por lotes a continuación está dirigido contra un administrado dll
o exe
, se mostrará de forma incorrecta como x86
, ya que la salida real de Corflags.exe
será un mensaje de error similar al siguiente:
corflags : error CF008 : The specified file does not have a valid managed header
@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.
Una aplicación más avanzada para que pueda encontrar aquí: CodePlex - ApiChange
Ejemplos:
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
una forma más sería utilizar dumpbin de las herramientas de Visual Studio en DLL y buscar la salida apropiada
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
Nota: Por encima de O/P es para la DLL de 32 bits
Uno más útil opción con Dumpbin.exe está/EXPORTACIONES, se le mostrará la función expuesta por el DLL
dumpbin.exe /EXPORTS <PATH OD THE DLL>
posible duplicado de [¿Cómo puedo determinar para qué plataforma se compila un ejecutable?] (http://stackoverflow.com/questions/197951/how-can-i-determine-for-which- platform-an-executable-is-compiled) – nawfal
Es posible que también desee consultar este: [check-if-unmanaged-dll-is-32-bit-or-64-bit] (http://stackoverflow.com/questions/1001404/check-if-unmanaged-dll-is-32-bit-or-64-bit). – Matt
En la versión posterior de CorFlags, correspondiente a .NET 4.5, ["32BIT" fue reemplazado por "32BITREQ" y "32BITPREF".] (Http://stackoverflow.com/questions/18608785/how-to-interpret-the- corflags-flags/23614024 # 23614024). –