Определите, является ли исполняемый файл (или библиотека) 32-или 64-разрядным (в Windows)
Я пытаюсь выяснить, компилируется ли данный исполняемый файл (или библиотека) для 32-бит или 64-бит из Python. Я запускаю Vista 64-бит и хотел бы определить, компилируется ли определенное приложение в Каталоге для 32-бит или 64-бит.
есть ли простой способ сделать это, используя только стандартные библиотеки Python (в настоящее время используя 2.5.4)?
3 ответов
API Windows для этого GetBinaryType
. Вы можете вызвать это из Python, используя pywin32:
import win32file
type=GetBinaryType("myfile.exe")
if type==win32file.SCS_32BIT_BINARY:
print "32 bit"
# And so on
Если вы хотите сделать это без pywin32, вам придется прочитать заголовок PE себя. Вот!--12-->пример в C#, и вот быстрый порт для 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()
Если вы используете Python 2.5 или более поздней версии в Windows, вы также можете использовать API Windows без pywin32 с помощью 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
затем используйте GetBinaryType так же, как и с win32file.GetBinaryType.
Примечание, вам придется реализовать handle_nonzero_success, который в основном выдает исключение, если возвращаемое значение равно 0.
я смог успешно использовать ответ Мартина Б в программе Python 3.5 после внесения этой корректировки:
s=f.read(2).decode(encoding="utf-8", errors="strict")
первоначально он отлично работал с моей программой в Python 2.7, но после внесения других необходимых изменений я обнаружил, что получаю b'MZ', и декодирование, похоже, исправляет это.