Python “版本文件”是什么样的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14624245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 11:59:11  来源:igfitidea点击:

What does a "version file" look like?

pythonwindowspyinstaller

提问by Hubro

I've been googling this for ages now without results. The PyInstallermanual says:

我一直在谷歌上搜索这个,但没有结果。该PyInstaller手册说:

--version-file=FILE
    add a version resource from FILE to the exe

That sounds nice. I want to put version information in my executables. The problem is that I have no clue what a "version file" looks like and I can't find a single example of one that I can use. I would consider an example of a version file as an acceptable answer to this question.

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



What I've tried

我试过的

The manual also says:

手册还说:

version
Windows NT family only. version='myversion.txt'. Use GrabVersion.py to steal a version resource from an executable, and then edit the ouput to create your own. (The syntax of version resources is so arcane that I wouldn't attempt to write one from scratch.)

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

I have attempted this with countless executable files from my system now. I just keep getting these errors:

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

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

on executables that has no version information, and:

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

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

On the rest.

剩下的。

采纳答案by Austin Phillips

Just had a quick look at the sources. It appears that the version file is expected to be Python source itself as the provided version file with be read and then eval'ed.

只是快速浏览了一下来源。似乎版本文件应该是 Python 源代码本身,因为提供的版本文件被读取然后eval“编辑”。

The GrabVersion.pyscript appears to generate errors as you've already found, so I modified the __repr__function of FixedFileInfoto manually convert tuple arguments to strings.

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

The Windows cmd.exehas a Windows version resource embedded, here's the output from GrabVersion.pywhich you would save to a file and feed to PyInstaller.

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

I haven't tried setting a version resource with PyInstaller so I'm not sure if this will work, I'd be interested in your feedback.

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

回答by J. Mulet

I had problems with Pyinstaller --version-fileoption in Python 3 and I solve it using Simple Version Resource Tool.

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

With this tool you can show the content of any version resource, just use the /vo option with any executable file: verpatch.exe /vo c:\Windows\System32\cmd.exe

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

To add a newversion resourceto an executable file, just follow this example:

要将版本资源添加到可执行文件,只需按照以下示例操作:

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"

回答by vampnerdlord

Create your Version file using an earlier answer save it as version.rc

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

Locate the filename.specfile open it. next in that script, locate the:

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

exe = EXE(pyz,...)

at the end of that entire section add this piece of code to automatically embed the version information on your exe file

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

version='version.rc'

Save it and then launch pyinstaller again and this time run the installer using this code:

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

pyinstaller filename.spec 

this will not only create the exe file itself but also include all of your version information as well.

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

In case you may not have thought about it, replace the filenamewith your program's filename

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

回答by tivnet

Please note that the version file uses Python code, so you can give it the .pyextension rather than .rc.

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

This will allow you to see it formatted nicely in your IDE, to check for errors (ignore "Unresolved References", of course), and to do anything else Python allows you to do.

这将允许您在您的 IDE 中看到它的格式很好,检查错误(忽略“未解析的引用”,当然),并做任何 Python 允许您做的事情。

回答by mac

I might be missing this in the previous answers, or maybe PyInstaller has been updated since these answers were originally provided, but the current docs for PyInstaller teach a fairly simple method for thisusing a command-line tool provided with PyInstaller (though I missed this section the first few times I looked to the docs).

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

Point this tool at an .exe file on your system that has "good looking" version info, and it will create a human-readable, commented, editable version resource file that you can use as a starting point.

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

pyi-grab_version executable_with_version_resource

which by default writes a file file_version_info.txtto the working directory.

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

Running the above on my local copy of svn.exe produces:

在我的本地 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])])
  ]
)

edit this to your purpose, and feed it back to PyInstaller as a --version-file, e.g.

根据您的目的编辑它,并将其作为--version-file.

pyinstaller [options] myscript.py --version-file file_version_info.txt