44

我已经在谷歌上搜索了很久没有结果。PyInstaller手册说:

--版本文件=文件
    将版本资源从 FILE 添加到 exe

听起来不错。我想将版本信息放在我的可执行文件中。问题是我不知道“版本文件”是什么样的,也找不到一个可以使用的示例。我会考虑一个版本文件的例子作为这个问题的可接受答案。


我试过的

手册还说:

版本
仅 Windows NT 系列。版本='myversion.txt'。使用 GrabVersion.py 从可执行文件中窃取版本资源,然后编辑输出以创建您自己的输出。(版本资源的语法太神秘了,我不会尝试从头开始编写。)

我现在已经尝试使用我系统中的无数可执行文件进行此操作。我只是不断收到这些错误:

回溯(最近一次通话最后):
  文件“C:\pyinstaller-2.0\utils\GrabVersion.py”,第 42 行,在
    vs = versioninfo.decode(sys.argv[1])
  解码中的文件“C:\pyinstaller-2.0\PyInstaller\utils\versioninfo.py”,第 33 行
    nm = win32api.EnumResourceNames(h, RT_VERSION)[0]
IndexError:列表索引超出范围

在没有版本信息的可执行文件上,并且:

回溯(最近一次通话最后):
  文件“C:\pyinstaller-2.0\utils\GrabVersion.py”,第 43 行,在
    打印与
  文件“C:\pyinstaller-2.0\PyInstaller\utils\versioninfo.py”,第 147 行,在 __repr__
    %(缩进,self.ffi.__repr__(缩进),缩进,
  文件“C:\pyinstaller-2.0\PyInstaller\utils\versioninfo.py”,第 251 行,在 __repr__
    "filevers=%s," % fv,
TypeError:字符串格式化期间并非所有参数都转换了

其余的。

4

6 回答 6

41

只是快速浏览了一下来源。看来,版本文件应该是 Python 源代码本身,因为提供的版本文件会被读取然后eval'ed。

GrabVersion.py正如您已经发现的那样,该脚本似乎会生成错误,因此我修改了手动将元组参数转换为字符串的__repr__函数。FixedFileInfo

Windowscmd.exe嵌入了 Windows 版本资源,GrabVersion.py这是您可以保存到文件并提供给 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])])
  ]
)

我没有尝试使用 PyInstaller 设置版本资源,所以我不确定这是否可行,我会对您的反馈感兴趣。

于 2013-01-31T12:47:28.407 回答
20

我可能在以前的答案中遗漏了这个,或者 PyInstaller 可能在最初提供这些答案后已经更新,但是 PyInstaller 的当前文档使用 PyInstaller提供的命令行工具教授了一个相当简单的方法(虽然我错过了这个前几次我查看文档的部分)。

将此工具指向您系统上具有“好看”版本信息的 .exe 文件,它将创建一个人类可读、注释、可编辑的版本资源文件,您可以将其用作起点。

pyi-grab_version executable_with_version_resource

默认情况下将文件写入file_version_info.txt工作目录。

在我的本地 svn.exe 副本上运行上述内容会产生:

# 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])])
  ]
)

根据您的目的编辑它,并将其作为 反馈给 PyInstaller --version-file,例如

pyinstaller [options] myscript.py --version-file file_version_info.txt
于 2018-03-28T20:00:02.083 回答
6

使用较早的答案创建您的版本文件,将其另存为version.rc

找到filename.spec文件打开它。接下来在该脚本中,找到:

exe = EXE(pyz,...)

在整个部分的末尾添加这段代码以自动将版本信息嵌入到您的 exe 文件中

version='version.rc'

保存它,然后再次启动 pyinstaller,这次使用以下代码运行安装程序:

pyinstaller filename.spec 

这不仅会创建 exe 文件本身,还会包括您的所有版本信息。

如果您可能没有考虑过,请将 替换为filename您的程序的文件名

于 2017-08-24T20:58:42.263 回答
4

我在 Python 3中遇到了 Pyinstaller --version-file选项的问题,我使用Simple Version Resource Tool解决了它。

使用此工具,您可以显示任何版本资源的内容,只需将 /vo 选项与任何可执行文件一起使用:verpatch.exe /vo c:\Windows\System32\cmd.exe

要将 版本资源添加到可执行文件,只需遵循以下示例:

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"
于 2016-04-09T15:16:48.693 回答
1

请注意,版本文件使用 Python 代码,因此您可以为其指定.py扩展名而不是.rc.

这将允许您在 IDE 中查看它的格式,检查错误(当然,忽略“未解析的引用”),并执行 Python 允许您执行的任何其他操作。

于 2017-10-05T15:45:40.210 回答
1

我在网上找到了一个用于创建版本文件的简单包:https ://pypi.org/project/pyinstaller-versionfile/#description 。根据链接中的信息安装后,应用一个简单易读的代码就足够了:

import pyinstaller_versionfile

pyinstaller_versionfile.create_versionfile(
    output_file="versionfile.txt",
    version="1.2.3.4",
    company_name="My Imaginary Company",
    file_description="Simple App",
    internal_name="Simple App",
    legal_copyright="© My Imaginary Company. All rights reserved.",
    original_filename="SimpleApp.exe",
    product_name="Simple App"
)

作为其操作的结果,我们获得了一个文件,例如在@mac 的答案中。该文件已准备好在 pyinstaller 中使用。

于 2022-01-28T15:56:47.353 回答