La última vez que hice una pregunta similar, pero eso era sobre svn relacionado con la información de versiones. Ahora me pregunto cómo consultar el atributo "Versión de archivo" de Windows, por ejemplo. un dll. Presté atención también a los módulos wmi y win32file sin éxito.Python windows File Version atributo
Respuesta
Puede usar la herramienta filever.exe para hacerlo. Aquí hay un hilo que explica how to do it from Python. Y aquí está el KB article con detalles sobre la herramienta.
Encontré esta solución en el sitio "timgolden". Funciona bien.
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)])
Mejor agregar una try/excepto en caso de que el archivo no tenga ningún atributo de número de versió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)
Salud!
se puede utilizar el módulo de pyWin32
de 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
Aquí es una función que lee todos los atributos de archivo como un diccionario:
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
Guau, excelente trabajo. ¿Cómo descubriste las cosas de StringFileInfo ... eso es lo que necesito. Muchas gracias. – iridescent
Para aquellos a los que les importa, 65536 es la mitad de DWORD (2 ** 16) – theannouncer
Aquí es una versión que también trabaja en la no de Windows entornos, usando el 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"
Esto lo veo perfectamente en el trabajo, pero lleva más de 10s hacerlo en un exe de 30mb :( – Steve
Me di cuenta de la fuente que puedes cortar ese 10s hasta 1s/2s al analizar solo el directorio de recursos, woo !: 'pe = pefile.PE (path, fast_load = True) pe.parse_data_directories (directorios = [pefile.DIRECTORY_ENTRY ['IMAGE_DIRECTORY_ENTRY_RESOURCE']])' – Steve
Agradable! Quería sugerir algo así. – flocki
Aquí hay una versión que no requiere ninguna biblioteca adicional. No podía utilizar win32api como todo el mundo había sugerido:
Desde: https://mail.python.org/pipermail//python-list/2006-November/402797.html
Sólo copiado aquí por si el original va a faltar.
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)
usados de esta manera:
print get_file_info(r'C:\WINDOWS\system32\calc.exe', 'FileVersion')
'WindowsError: excepción: violación de acceso al leer 0x0000000082E47858' al obtener las páginas de códigos. string_at (r.value, l.value) 'falla allí :( – ewerybody
- 1. XCode-Project file .pbxproj - ¿cómo manejarlo en Version Control?
- 2. Windows 8 Consumer Preview Wrong Major Version?
- 3. Python argparse required = True but --version function?
- 4. Downgrade NodeJs Version y express version
- 5. CodeSigning a IPA file using only Windows
- 6. Sync File System comando para Windows
- 7. Windows Batch file - pipe to FIND
- 8. JAVA_HOME y java -version
- 9. Java URL ("file: //") no funciona en Windows XP
- 10. Eclipse Version
- 11. atributo de clase python
- 12. Mocking file objects or iterables in python
- 13. Python + Django + VirtualEnv + Windows
- 14. ¿Cómo deshacerse de la doble barra invertida en python windows file path string?
- 15. Python ctypes: objeto de archivo Python <-> C FILE *
- 16. Hacer que TeamCity Version Match .NET Assembly Version
- 17. Windows Batch File - Move File no funciona en el Programador de tareas solamente
- 18. fwrite ahoga en "<? Xml version"
- 19. subparser argparse opcional (para --version)
- 20. Python PIL no tiene ningún atributo 'Imagen'
- 21. SVN mark major version
- 22. JPA @Version: cómo usarlo?
- 23. Apex Code Version Control
- 24. .NET framework version used
- 25. Java - JPA - @Version Anotación
- 26. MySQL Version Control - Subversion
- 27. ASP.Net Version/Build Number
- 28. Greasemonkey Version Script constante
- 29. WPF WebBrowser Browser Version
- 30. PLC Version Control
funciona perfectamente y simple de todas las soluciones! Gracias. – 0x1mason
¿Hay alguna forma en que pueda obtener la descripción del archivo también? No vi ningún método en FileSystemObject que haga eso :( –
Funcionó como un amuleto. ¡Gracias! – Suneelm