python - compile - ¿Qué aspecto tiene un "archivo de versión"?
python executable (5)
He estado buscando en Google por años sin resultados. El manual de PyInstaller dice:
--version-file=FILE add a version resource from FILE to the exe
Eso suena bien. Quiero poner información de versión en mis ejecutables. El problema es que no tengo ni idea de cómo es un "archivo de versión" y no puedo encontrar un solo ejemplo de uno que pueda usar. Consideraría un ejemplo de un archivo de versión como una respuesta aceptable a esta pregunta.
Lo que he intentado
El manual también dice:
versión
Sólo la familia de Windows NT. version = ''myversion.txt''. Use GrabVersion.py para robar un recurso de versión de un ejecutable y luego edite la salida para crear la suya propia. (La sintaxis de los recursos de la versión es tan arcana que no intentaría escribir uno desde cero).
He intentado esto con innumerables archivos ejecutables de mi sistema ahora. Sigo recibiendo estos errores:
Traceback (most recent call last): File "C:/pyinstaller-2.0/utils/GrabVersion.py", line 42, in vs = versioninfo.decode(sys.argv[1]) File "C:/pyinstaller-2.0/PyInstaller/utils/versioninfo.py", line 33, in decode nm = win32api.EnumResourceNames(h, RT_VERSION)[0] IndexError: list index out of range
en ejecutables que no tienen información de versión, y:
Traceback (most recent call last): File "C:/pyinstaller-2.0/utils/GrabVersion.py", line 43, in print vs File "C:/pyinstaller-2.0/PyInstaller/utils/versioninfo.py", line 147, in __repr__ % (indent, self.ffi.__repr__(indent), indent, File "C:/pyinstaller-2.0/PyInstaller/utils/versioninfo.py", line 251, in __repr__ "filevers=%s," % fv, TypeError: not all arguments converted during string formatting
En el resto.
Cree su archivo de versión con una respuesta anterior, guárdelo como version.rc
Localice el archivo filename.spec
ábralo. A continuación en ese script, busque el:
exe = EXE(pyz,...)
al final de toda la sección, agregue este fragmento de código para incrustar automáticamente la información de la versión en su archivo exe
version=''version.rc''
Guárdelo y luego inicie Pyinstaller de nuevo y esta vez ejecute el instalador usando este código:
pyinstaller filename.spec
esto no solo creará el archivo exe en sí, sino que también incluirá toda la información de su versión.
En caso de que no lo haya pensado, reemplace el filename
con el filename
de su programa
Puede que me falte esto en las respuestas anteriores, o tal vez PyInstaller se haya actualizado desde que se proporcionaron originalmente, pero los documentos actuales para PyInstaller enseñan un método bastante simple para esto utilizando una herramienta de línea de comandos provista con PyInstaller sección las primeras veces que miré a los documentos).
Apunte esta herramienta a un archivo .exe en su sistema que tenga información de versión "atractiva", y creará un archivo de recursos de versión editable, comentado y legible, que puede usar como punto de partida.
pyi-grab_version executable_with_version_resource
que por defecto escribe un archivo file_version_info.txt
en el directorio de trabajo.
Ejecutar lo anterior en mi copia local de svn.exe produce:
# UTF-8
#
# For more details about fixed file info ''ffi'' see:
# http://msdn.microsoft.com/en-us/library/ms646997.aspx
VSVersionInfo(
ffi=FixedFileInfo(
# filevers and prodvers should be always a tuple with four items: (1, 2, 3, 4)
# Set not needed items to zero 0.
filevers=(1, 9, 7, 30920),
prodvers=(1, 9, 7, 30920),
# Contains a bitmask that specifies the valid bits ''flags''r
mask=0x3f,
# Contains a bitmask that specifies the Boolean attributes of the file.
flags=0x0,
# The operating system for which this file was designed.
# 0x4 - NT and there is no need to change it.
OS=0x4,
# The general type of file.
# 0x1 - the file is an application.
fileType=0x1,
# The function of the file.
# 0x0 - the function is not defined for this fileType
subtype=0x0,
# Creation date and time stamp.
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u''040904B0'',
[StringStruct(u''CompanyName'', u''Apache Software Foundation''),
StringStruct(u''FileDescription'', u''svn''),
StringStruct(u''FileVersion'', u''1.9.7''),
StringStruct(u''InternalName'', u''SVN''),
StringStruct(u''LegalCopyright'', u''Copyright (c) The Apache Software Foundation''),
StringStruct(u''OriginalFilename'', u''svn.exe''),
StringStruct(u''ProductName'', u''Subversion''),
StringStruct(u''ProductVersion'', u''1.9.7 (r1800392)'')])
]),
VarFileInfo([VarStruct(u''Translation'', [1033, 1200])])
]
)
edítelo según su propósito y envíelo a PyInstaller como un --version-file
versión, por ejemplo,
pyinstaller [options] myscript.py --version-file file_version_info.txt
Tenga en cuenta que el archivo de la versión es un código de Python, por lo que puede darle la extensión .py
para verlo bien formateado en su IDE, para verificar errores (ignorar Referencias no resueltas, por supuesto), y hacer lo que Python le permita hacer.
Tuve problemas con la opción de archivo de versión Pyinstaller en Python 3 y lo resuelvo utilizando la herramienta de recursos de versión simple .
Con esta herramienta puede mostrar el contenido de cualquier recurso de versión , solo use la opción / vo con cualquier archivo ejecutable: verpatch.exe /vo c:/Windows/System32/cmd.exe
Para agregar un nuevo recurso de versión a un archivo ejecutable, simplemente siga este ejemplo:
verpatch.exe script.exe 1.0.0.0 /va /pv 1.0.0.0 /s description "Your product description" /s product "Your product name" /s copyright "Your company name, 2016" /s company "Your company name"
Acabo de echar un vistazo rápido a las fuentes. Parece que se espera que el archivo de la versión sea la fuente de Python como el archivo de la versión que se debe leer y eval
.
La GrabVersion.py
comandos GrabVersion.py
parece generar errores como ya ha encontrado, por lo que modifiqué la función FixedFileInfo
de FixedFileInfo
para convertir manualmente los argumentos de la tupla en cadenas.
El cmd.exe
Windows tiene un recurso de versión de Windows incorporado, aquí está el resultado de GrabVersion.py
que guardaría en un archivo y alimentaría a PyInstaller.
VSVersionInfo(
ffi=FixedFileInfo(
filevers=(6, 1, 7601, 17514),
prodvers=(6, 1, 7601, 17514),
mask=0x3f,
flags=0x0,
OS=0x40004,
fileType=0x1,
subtype=0x0,
date=(0, 0)
),
kids=[
StringFileInfo(
[
StringTable(
u''040904B0'',
[StringStruct(u''CompanyName'', u''Microsoft Corporation''),
StringStruct(u''FileDescription'', u''Windows Command Processor''),
StringStruct(u''FileVersion'', u''6.1.7601.17514 (win7sp1_rtm.101119-1850)''),
StringStruct(u''InternalName'', u''cmd''),
StringStruct(u''LegalCopyright'', u''/xa9 Microsoft Corporation. All rights reserved.''),
StringStruct(u''OriginalFilename'', u''Cmd.Exe''),
StringStruct(u''ProductName'', u''Microsoft/xae Windows/xae Operating System''),
StringStruct(u''ProductVersion'', u''6.1.7601.17514'')])
]),
VarFileInfo([VarStruct(u''Translation'', [1033, 1200])])
]
)
No he intentado configurar un recurso de versión con PyInstaller, así que no estoy seguro de si esto funcionará, me interesaría su opinión.