2009-08-28 13 views
7

Estoy tratando de averiguar si un archivo ejecutable (o biblioteca) determinado se compila para 32 bits o 64 bits de Python. Estoy ejecutando Vista de 64 bits y me gustaría determinar si una determinada aplicación en un directorio se compila para 32 bits o 64 bits.Determinar si un archivo ejecutable (o biblioteca) es de 32 o 64 bits (en Windows)

¿Hay una manera simple de hacer esto usando solo las bibliotecas estándar de Python (actualmente usando 2.5.4)?

Respuesta

18

La API de Windows para esto es GetBinaryType. Usted puede llamar a esto desde Python usando pywin32:

import win32file 
type=GetBinaryType("myfile.exe") 
if type==win32file.SCS_32BIT_BINARY: 
    print "32 bit" 
# And so on 

Si desea hacer esto sin pywin32, que tendrá que leer el PE header mismo. Aquí es an example en C#, y aquí es un puerto rápido a Python:

import struct 

IMAGE_FILE_MACHINE_I386=332 
IMAGE_FILE_MACHINE_IA64=512 
IMAGE_FILE_MACHINE_AMD64=34404 

f=open("c:\windows\explorer.exe", "rb") 

s=f.read(2) 
if s!="MZ": 
    print "Not an EXE file" 
else: 
    f.seek(60) 
    s=f.read(4) 
    header_offset=struct.unpack("<L", s)[0] 
    f.seek(header_offset+4) 
    s=f.read(2) 
    machine=struct.unpack("<H", s)[0] 

    if machine==IMAGE_FILE_MACHINE_I386: 
     print "IA-32 (32-bit x86)" 
    elif machine==IMAGE_FILE_MACHINE_IA64: 
     print "IA-64 (Itanium)" 
    elif machine==IMAGE_FILE_MACHINE_AMD64: 
     print "AMD64 (64-bit x86)" 
    else: 
     print "Unknown architecture" 

f.close() 
+0

Sería bueno si pudiera obtener esta información sin usar el módulo pywin32. – pkit

+1

Acaba de editar la respuesta para mostrar cómo puede hacerlo sin pywin32. –

+0

@Martin. Gracias por los enlaces, veré si puedo armar algo. – pkit

4

Si se está utilizando Python 2.5 o posterior en Windows, también se puede utilizar la API de Windows sin pywin32 utilizando ctypes.

from ctypes import windll, POINTER 
from ctypes.wintypes import LPWSTR, DWORD, BOOL 

SCS_32BIT_BINARY = 0 # A 32-bit Windows-based application 
SCS_64BIT_BINARY = 6 # A 64-bit Windows-based application 
SCS_DOS_BINARY = 1 # An MS-DOS-based application 
SCS_OS216_BINARY = 5 # A 16-bit OS/2-based application 
SCS_PIF_BINARY = 3 # A PIF file that executes an MS-DOS-based application 
SCS_POSIX_BINARY = 4 # A POSIX-based application 
SCS_WOW_BINARY = 2 # A 16-bit Windows-based application 

_GetBinaryType = windll.kernel32.GetBinaryTypeW 
_GetBinaryType.argtypes = (LPWSTR, POINTER(DWORD)) 
_GetBinaryType.restype = BOOL 

def GetBinaryType(filepath): 
    res = DWORD() 
    handle_nonzero_success(_GetBinaryType(filepath, res)) 
    return res 

A continuación, utilice GetBinaryType al igual que lo haría con win32file.GetBinaryType.

Nota, se tendría que implementar handle_nonzero_success, que básicamente se produce una excepción si el valor de retorno es 0.

0

pude usar la respuesta de Martin B con éxito en un programa de Python 3.5 después de hacer este ajuste:

s=f.read(2).decode(encoding="utf-8", errors="strict") 

Originalmente funcionó bien con mi programa en Python 2.7, pero después de hacer otros cambios necesarios, descubrí que estaba obteniendo b'MZ ', y la decodificación parece solucionar esto.

Cuestiones relacionadas