J'essaie de savoir si une exécutable (ou une bibliothèque) donnée est compilée pour 32 bits ou 64 bits de Python. Je rencontre Vista 64-bits et je voudrais déterminer si une certaine application d'un répertoire est compilée pour 32 bits ou 64 bits. P>
Y a-t-il un moyen simple de le faire en utilisant uniquement les bibliothèques Python standard (en utilisant actuellement 2,5,4)? P>
5 Réponses :
L'API Windows pour cela est Si vous voulez faire cela sans pywin32, vous devrez lire le en-tête PE vous-même. Voici un exemple en C #, et voici une Port rapide à Python: P> getbinairetype
. Vous pouvez appeler cela de python à l'aide de pywin32 : 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()
Ce serait bien si je pouvais obtenir ces informations sans utiliser le module PYWIN32.
Je viens de modifier la réponse pour montrer comment vous pouvez le faire sans pywin32.
@Martin. Merci pour les liens, je verrai si je peux mettre quelque chose ensemble.
Il suffit d'ajouter un port de l'exemple C # à Python.
Le fichier ne devrait-il pas être ouvert en mode binaire?
Cette affiche « l'architecture inconnue » sur ma machine. Les rapports variables de la machine -31132. Aucune suggestion?
Mon mauvais - image_file_machine_ia64 est itanium. -31132 (ou 34404 non signé) est AMD64 (alias 64 bits X86). Vous n'avez pas de système de 64 bits que je peux tester cela, mais j'espère que cela devrait fonctionner maintenant.
J'ai pu utiliser cette solution (Python 3.5) après avoir incorporé les modifications suggérées dans la réponse fournie ci-dessous par Jason R Coombs.
Si vous exécutez Python 2.5 ou plus tard sur Windows, vous pouvez également utiliser l'API Windows sans pywin32 à l'aide de 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
J'ai pu utiliser la réponse de Martin B avec succès dans un programme Python 3.5 après avoir effectué ce réglage:
s=f.read(2).decode(encoding="utf-8", errors="strict")
win32file.getbinairetype code>. Li>
-
L'exécution également sur un fichier .PYD ne fonctionne pas, même s'il est renommé à un fichier .dll. Voir Suivant: P>
Pythonwin.exe: 32 bit
win32ui.pyd: Traceback (most recent call last):
File "C:/Users/rdboylan/Documents/Wk devel/bitness.py", line 14, in <module>
type = win32file.GetBinaryType(str(mytemp))
pywintypes.error: (193, 'GetBinaryType', '%1 is not a valid Win32 application.')
J'ai édité Réponse pour fonctionner avec Python 3, ajouté avec code > SUPPORTATIONS ET ARM / ARM64 Support:
import struct
IMAGE_FILE_MACHINE_I386 = 332
IMAGE_FILE_MACHINE_IA64 = 512
IMAGE_FILE_MACHINE_AMD64 = 34404
IMAGE_FILE_MACHINE_ARM = 452
IMAGE_FILE_MACHINE_AARCH64 = 43620
with open('foo.exe', 'rb') as f:
s = f.read(2)
if s != b'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)')
elif machine == IMAGE_FILE_MACHINE_ARM:
print('ARM eabi (32-bit)')
elif machine == IMAGE_FILE_MACHINE_AARCH64:
print('AArch64 (ARM-64, 64-bit)')
else:
print(f'Unknown architecture {machine}')