我试图找出是否从Python编译了32位或64位的给定可执行文件(或库)。我正在运行Vista 64位,并想确定目录中的某个应用程序是否编译为32位或64位。
有没有一种简单的方法可以只使用标准的Python库(目前使用2.5.4)?
答案 0 :(得分:20)
Windows API就是GetBinaryType
。您可以使用pywin32:
import win32file
type=GetBinaryType("myfile.exe")
if type==win32file.SCS_32BIT_BINARY:
print "32 bit"
# And so on
如果你想在没有pywin32的情况下这样做,你必须自己阅读PE header。这是C#中的an example,这里是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()
答案 1 :(得分:4)
如果您在Windows上运行Python 2.5或更高版本,则还可以使用不带pywin32的Windows API使用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
然后像使用win32file.GetBinaryType一样使用GetBinaryType。
注意,你必须实现handle_nonzero_success,如果返回值为0,它基本上会抛出异常。
答案 2 :(得分:2)
我编辑了 Martin B's 答案以使用 Python 3,添加了 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}')
语句和 ARM/ARM64 支持:
public class NodeT
{
private int val;
NodeT left;
NodeT right;
public NodeT(int val)
{
this.val = val;
}
public void setData(int val)
{
this.val = val;
}
public int getData()
{
return this.val;
}
//however you defined getRight, and getLeft
}
void inorder()
{
Stack<NodeT> stack = new Stack<>();
NodeT current = this.root;
while(!(current == null && stack.empty()))
{
if(current == null)
{
current = stack.peek().getRight();
System.out.print(stack.pop().getData());//HERE
}
else
{
stack.push(current);
current = current.getLeft();
}
}
System.out.println();
}
答案 3 :(得分:1)
在进行此调整后,我能够在Python 3.5程序中成功使用Martin B的答案:
s=f.read(2).decode(encoding="utf-8", errors="strict")
最初它在我的Python 2.7程序中运行得很好,但在进行了其他必要的更改之后,我发现我得到了b&#39; MZ&#39;并且解码它似乎解决了这个问题。
答案 4 :(得分:0)
win32file.GetBinaryType
。即使将其重命名为.dll,也无法在.pyd文件上运行该文件。见下:
import shutil
import win32file
from pathlib import Path
myDir = Path("C:\\Users\\rdboylan\\AppData\\Roaming\\Python\\Python37\\site-packages\\pythonwin")
for fn in ("Pythonwin.exe", "win32ui.pyd"):
print(fn, end=": ")
myf = myDir / fn
if myf.suffix == ".pyd":
mytemp = myf.with_suffix(".dll")
if mytemp.exists():
raise "Can not create temporary dll since {} exists".format(mytemp)
shutil.copyfile(myf, mytemp)
type = win32file.GetBinaryType(str(mytemp))
mytemp.unlink()
else:
type=win32file.GetBinaryType(str(myf))
if type==win32file.SCS_32BIT_BINARY:
print("32 bit")
else:
print("Something else")
# And so on
结果
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.')