确定可执行文件(或库)是32位还是64位(在Windows上)

时间:2009-08-28 08:05:38

标签: python windows dll 64-bit executable

我试图找出是否从Python编译了32位或64位的给定可执行文件(或库)。我正在运行Vista 64位,并想确定目录中的某个应用程序是否编译为32位或64位。

有没有一种简单的方法可以只使用标准的Python库(目前使用2.5.4)?

5 个答案:

答案 0 :(得分:20)

Windows API就是GetBinaryType。您可以使用pywin32

从Python调用此方法
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)

  1. 使用Python 3.7(在64位Win 7上为32位),最高答案中的第一个代码片段对我而言不运行。它失败,因为GetBinaryType是未知符号。解决方法是使用win32file.GetBinaryType
  2. 即使将其重命名为.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.')