2009-08-28 32 views
7

Tôi đang cố gắng tìm hiểu xem một tập tin thực thi (hoặc thư viện) đã được biên soạn cho 32 bit hay 64 bit từ Python. Tôi đang chạy Vista 64-bit và muốn xác định nếu một ứng dụng nhất định trong một thư mục được biên dịch cho 32-bit hoặc 64-bit.Xác định xem một tập tin thực thi (hoặc thư viện) là 32 -hoặc 64 bit (trên Windows)

Có cách nào đơn giản để thực hiện việc này bằng cách sử dụng các thư viện Python chuẩn (hiện đang sử dụng 2.5.4) không?

Trả lời

18

API Windows cho điều này là GetBinaryType. Bạn có thể gọi đây từ Python sử dụng pywin32:

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

Nếu bạn muốn làm điều này mà không PyWin32, bạn sẽ phải đọc các PE header mình. Dưới đây là an example trong C#, và đây là một cổng nhanh chóng để 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

Sẽ thật tuyệt nếu tôi có thể nhận được thông tin này mà không cần sử dụng mô-đun pywin32. – pkit

+1

Chỉ cần chỉnh sửa câu trả lời để cho thấy cách bạn có thể làm điều này mà không cần pywin32. –

+0

@Martin. Cảm ơn các liên kết, tôi sẽ xem liệu tôi có thể đặt một thứ gì đó cùng nhau không. – pkit

4

Nếu bạn đang chạy Python 2.5 hoặc mới hơn trên Windows, bạn cũng có thể sử dụng API của Windows mà không cần PyWin32 bằng cách sử dụng 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 

Sau đó, sử dụng GetBinaryType giống như bạn làm với win32file.GetBinaryType.

Lưu ý, bạn sẽ phải thực hiện handle_nonzero_success, mà về cơ bản ném một ngoại lệ nếu giá trị trả về là 0.

0

tôi đã có thể sử dụng câu trả lời Martin B thành công trong một chương trình Python 3.5 sau khi thực hiện điều chỉnh này:

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

Ban đầu nó hoạt động tốt với chương trình của tôi bằng Python 2.7, nhưng sau khi thực hiện các thay đổi cần thiết khác, tôi phát hiện ra mình đã nhận được b'MZ 'và giải mã nó xuất hiện để sửa lỗi này.

Các vấn đề liên quan