代码之家  ›  专栏  ›  技术社区  ›  pkit

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

  •  8
  • pkit  · 技术社区  · 15 年前

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

    是否有一种简单的方法可以只使用标准的python库(目前使用的是2.5.4)来实现这一点?

    4 回复  |  直到 5 年前
        1
  •  20
  •   Martin B    15 年前

    用于此的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 你自己。这里是 an example 在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()
    
        2
  •  4
  •   Jason R. Coombs    15 年前

    如果您在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,它基本上会抛出一个异常。

        3
  •  1
  •   thesis    8 年前

    在进行了以下调整之后,我在python 3.5程序中成功地使用了MartinB的答案:

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

    最初它与我在python 2.7中的程序一起工作得很好,但是在做了其他必要的更改之后,我发现我得到了b'mz',解码它似乎可以解决这个问题。

        4
  •  0
  •   Vasily Ryabov    5 年前
    1. 使用64位Win7上的32位python 3.7,顶级答案中的第一个代码片段对我来说并不适用。它失败,因为GetBinaryType是未知符号。解决方案是使用 win32file.GetBinaryType .
    2. 在.pyd文件上运行它也不起作用,即使它被重命名为.dll。见下一步:

      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.')
      
    推荐文章