2009-02-24 31 views
20

Lần trước tôi đã hỏi một câu hỏi tương tự nhưng đó là về thông tin phiên bản liên quan đến svn. Bây giờ tôi tự hỏi làm thế nào để truy vấn cửa sổ "File phiên bản" thuộc tính về ví dụ. một dll. Tôi đã chú ý đến các mô-đun wmi và win32file cũng như không thành công.Cửa sổ Python Thuộc tính Phiên bản Tệp

Trả lời

4

Tôi tìm thấy giải pháp này tại trang "timgolden". Hoạt động tốt.

from win32api import GetFileVersionInfo, LOWORD, HIWORD 

def get_version_number (filename): 
    info = GetFileVersionInfo (filename, "\\") 
    ms = info['FileVersionMS'] 
    ls = info['FileVersionLS'] 
    return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls) 

if __name__ == '__main__': 
    import os 
    filename = os.environ["COMSPEC"] 
    print ".".join ([str (i) for i in get_version_number (filename)]) 
18

Tốt hơn để thêm thử/trừ trường hợp tệp không có thuộc tính số phiên bản.

filever.py


from win32api import GetFileVersionInfo, LOWORD, HIWORD 

def get_version_number (filename): 
    try: 
     info = GetFileVersionInfo (filename, "\\") 
     ms = info['FileVersionMS'] 
     ls = info['FileVersionLS'] 
     return HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls) 
    except: 
     return 0,0,0,0 

if __name__ == '__main__': 
    import os 
    filename = os.environ["COMSPEC"] 
    print ".".join ([str (i) for i in get_version_number (filename)]) 

yourscript.py:


import os,filever 

myPath="C:\\path\\to\\check" 

for root, dirs, files in os.walk(myPath): 
    for file in files: 
     file = file.lower() # Convert .EXE to .exe so next line works 
     if (file.count('.exe') or file.count('.dll')): # Check only exe or dll files 
      fullPathToFile=os.path.join(root,file) 
      major,minor,subminor,revision=filever.get_version_number(fullPathToFile) 
      print "Filename: %s \t Version: %s.%s.%s.%s" % (file,major,minor,subminor,revision) 

Cheers!

10

Bạn có thể sử dụng các mô-đun pyWin32 từ http://sourceforge.net/projects/pywin32/:

from win32com.client import Dispatch 

ver_parser = Dispatch('Scripting.FileSystemObject') 
info = ver_parser.GetFileVersion(path) 

if info == 'No Version Information Available': 
    info = None 
+1

công trình hoàn hảo và đơn giản nhất của tất cả các giải pháp! cảm ơn. – 0x1mason

+0

Có cách nào tôi có thể nhận được mô tả tệp không? Tôi không thấy bất kỳ phương pháp nào trong FileSystemObject mà làm điều đó: ( –

+0

Làm việc như một say mê. Cảm ơn bạn !! – Suneelm

21

Đây là một chức năng mà đọc thuộc tính tất cả các tập tin như một cuốn từ điển:

import win32api 

#============================================================================== 
def getFileProperties(fname): 
#============================================================================== 
    """ 
    Read all properties of the given file return them as a dictionary. 
    """ 
    propNames = ('Comments', 'InternalName', 'ProductName', 
     'CompanyName', 'LegalCopyright', 'ProductVersion', 
     'FileDescription', 'LegalTrademarks', 'PrivateBuild', 
     'FileVersion', 'OriginalFilename', 'SpecialBuild') 

    props = {'FixedFileInfo': None, 'StringFileInfo': None, 'FileVersion': None} 

    try: 
     # backslash as parm returns dictionary of numeric info corresponding to VS_FIXEDFILEINFO struc 
     fixedInfo = win32api.GetFileVersionInfo(fname, '\\') 
     props['FixedFileInfo'] = fixedInfo 
     props['FileVersion'] = "%d.%d.%d.%d" % (fixedInfo['FileVersionMS']/65536, 
       fixedInfo['FileVersionMS'] % 65536, fixedInfo['FileVersionLS']/65536, 
       fixedInfo['FileVersionLS'] % 65536) 

     # \VarFileInfo\Translation returns list of available (language, codepage) 
     # pairs that can be used to retreive string info. We are using only the first pair. 
     lang, codepage = win32api.GetFileVersionInfo(fname, '\\VarFileInfo\\Translation')[0] 

     # any other must be of the form \StringfileInfo\%04X%04X\parm_name, middle 
     # two are language/codepage pair returned from above 

     strInfo = {} 
     for propName in propNames: 
      strInfoPath = u'\\StringFileInfo\\%04X%04X\\%s' % (lang, codepage, propName) 
      ## print str_info 
      strInfo[propName] = win32api.GetFileVersionInfo(fname, strInfoPath) 

     props['StringFileInfo'] = strInfo 
    except: 
     pass 

    return props 
+1

Wow, công việc tuyệt vời .. Làm thế nào bạn thậm chí tìm ra những thứ StringFileInfo .. đó là những gì tôi cần.Cảm ơn rất nhiều – iridescent

+1

Đối với những người quan tâm, 65536 là một nửa DWORD (2 ** 16) – theannouncer

10

Đây là một phiên bản đó cũng hoạt động trong không phải Windows môi trường, sử dụng pefile-module:

import pefile 

def LOWORD(dword): 
    return dword & 0x0000ffff 
def HIWORD(dword): 
    return dword >> 16 
def get_product_version(path): 

    pe = pefile.PE(path) 
    #print PE.dump_info() 

    ms = pe.VS_FIXEDFILEINFO.ProductVersionMS 
    ls = pe.VS_FIXEDFILEINFO.ProductVersionLS 
    return (HIWORD (ms), LOWORD (ms), HIWORD (ls), LOWORD (ls)) 


if __name__ == "__main__": 
    import sys 
    try: 
     print "%d.%d.%d.%d" % get_product_version(sys.argv[1]) 
    except: 
     print "Version info not available. Maybe the file is not a Windows executable" 
+0

Tôi tìm thấy điều này cho công việc một cách hoàn hảo, nhưng phải mất hơn 10s để làm điều đó trên một exe 30mb: ( – Steve

+3

Tôi đã tìm ra từ nguồn mà bạn có thể cắt 10s xuống 1s/2s bằng cách phân tích cú pháp thư mục tài nguyên, woo !: 'pe = pefile.PE (đường dẫn, fast_load = True) pe.parse_data_directories (directories = [pefile.DIRECTORY_ENTRY ['IMAGE_DIRECTORY_ENTRY_RESOURCE']])' – Steve

+0

Rất đẹp! Tôi muốn đề xuất điều gì đó như thế. – flocki

2

Đây là phiên bản không yêu cầu bất kỳ thư viện bổ sung nào. Tôi không thể sử dụng win32api như tất cả mọi người đã đề nghị:

Từ: https://mail.python.org/pipermail//python-list/2006-November/402797.html

Chỉ sao chép ở đây trong trường hợp bản gốc bị mất tích.

import array 
from ctypes import * 

def get_file_info(filename, info): 
    """ 
    Extract information from a file. 
    """ 
    # Get size needed for buffer (0 if no info) 
    size = windll.version.GetFileVersionInfoSizeA(filename, None) 
    # If no info in file -> empty string 
    if not size: 
     return '' 
    # Create buffer 
    res = create_string_buffer(size) 
    # Load file informations into buffer res 
    windll.version.GetFileVersionInfoA(filename, None, size, res) 
    r = c_uint() 
    l = c_uint() 
    # Look for codepages 
    windll.version.VerQueryValueA(res, '\\VarFileInfo\\Translation', 
            byref(r), byref(l)) 
    # If no codepage -> empty string 
    if not l.value: 
     return '' 
    # Take the first codepage (what else ?) 
    codepages = array.array('H', string_at(r.value, l.value)) 
    codepage = tuple(codepages[:2].tolist()) 
    # Extract information 
    windll.version.VerQueryValueA(res, ('\\StringFileInfo\\%04x%04x\\' 
+ info) % codepage, 
             byref(r), byref(l)) 
    return string_at(r.value, l.value) 

Được sử dụng như sau:

print get_file_info(r'C:\WINDOWS\system32\calc.exe', 'FileVersion') 
+0

'WindowsError: exception: truy cập vi phạm đọc 0x0000000082E47858' khi nhận được các mã. string_at (r.value, l.value) 'không có: ( – ewerybody

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