Das letzte Mal fragte ich eine ähnliche Frage, aber das war über SVN verwandte Versionsinformationen. Jetzt frage ich mich, wie man Windows "Dateiversion" -Attribut über zB abfragt. eine DLL. Ich habe auch ohne Erfolg auf wmi und win32file Module geachtet.Python Windows Datei Version Attribut
Antwort
Sie können dazu das Tool filever.exe verwenden. Hier ist ein Thread, der how to do it from Python erklärt. Und hier ist die KB article mit Details über das Werkzeug.
Ich fand diese Lösung bei "timgolden" Website. Funktioniert gut.
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)])
Lieber einen Versuch hinzufügen/außer für den Fall, dass die Datei keine Versionsnummer Attribut hat.
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)
Prost!
Sie können das pyWin32
Modul von 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
Hier ist eine Funktion, die alle Datei als Wörterbuch-Attribute lautet:
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
Wow, tolle Arbeit. Wie hast du sogar die StringFileInfo Zeug .. das ist was ich brauche. Vielen Dank. – iridescent
Für diejenigen, die sich interessieren, 65536 ist ein halbes DWORD (2 ** 16) – theannouncer
Hier ist eine Version, die in Nicht-Windows funktioniert auch Umgebungen mit dem 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"
Ich finde das perfekt, aber es dauert über 10s, um es auf einer 30mb exe zu tun :( – Steve
Ich habe herausgefunden, aus der Quelle, die Sie schneiden können Diese 10s bis zu 1s/2s durch Parsing nur das Ressourcenverzeichnis, woo !: 'pe = pefile.PE (Pfad, fast_load = True) pe.parse_data_directories (Verzeichnisse = [pefile.DIRECTORY_ENTRY ['IMAGE_DIRECTORY_ENTRY_RESOURCE']])' – Steve
Nice! Ich wollte so etwas vorschlagen. – flocki
Hier ist eine Version, die keine zusätzlichen Bibliotheken benötigt. Ich konnte nicht verwenden win32api wie jeder vorgeschlagen hatte:
Von: https://mail.python.org/pipermail//python-list/2006-November/402797.html
Nur hier im Fall kopiert das Original verloren geht.
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)
wie so verwendet:
print get_file_info(r'C:\WINDOWS\system32\calc.exe', 'FileVersion')
'WindowsError: Ausnahme: Zugriffsverletzung beim Lesen der Codepages 0x0000000082E47858 zu lesen.' string_at (r.value, l.value) 'scheitert dort :( – ewerybody
funktioniert perfekt und einfachste aller Lösungen! Vielen Dank. – 0x1mason
Kann ich die Dateibeschreibung auch irgendwie bekommen? Ich habe keine Methode in FileSystemObject gesehen, die das tut :( –
Arbeitete wie ein Charme. Vielen Dank! – Suneelm