Qt 和 Windows 可执行版本信息
Qt and Windows Executable Version Information
我的 Windows Qt 小部件应用程序使用 "version.h" 文件和 "RC" 文件来填充可执行文件的版本信息字符串。
version.h 看起来像这样...
#ifndef VERSION_H
#define VERSION_H
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_BUILD 3
#define VER_FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_BUILD,0
#define STR_FILEVERSION VERSION_MAJOR##"."##VERSION_MINOR##"."VERSION_BUILD##".0"
// Keep the product version as fixed
#define VER_PRODUCTVERSION 1.0.0.0
#define STR_PRODUCTVERSION "1.0.0.0[=11=]"
#define STR_COMPANYNAME "MyCompany"
#define STR_FILEDESCRIPTION "MyFile"
#define STR_INTERNALNAME "MyFile"
#define STR_LEGALCOPYRIGHT "Copyright © 2017 MyCompany"
#define STR_LEGALTRADEMARKS1 "All Rights Reserved"
#define STR_LEGALTRADEMARKS2 STR_LEGALTRADEMARKS1
#define STR_ORIGINALFILENAME "MyApp.exe"
#define STR_PRODUCTNAME "MyApp"
#define STR_COMPANYDOMAIN "mywebsite.com"
#endif // VERSION_H
RC 文件如下所示:
IDI_APP_ICON ICON DISCARDABLE "MyApp.ico"
#include <windows.h>
#include "version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", STR_COMPANYNAME
VALUE "FileDescription", STR_FILEDESCRIPTION
VALUE "FileVersion", STR_FILEVERSION
VALUE "InternalName", STR_INTERNALNAME
VALUE "LegalCopyright", STR_LEGALCOPYRIGHT
VALUE "LegalTrademarks1", STR_LEGALTRADEMARKS1
VALUE "LegalTrademarks2", STR_LEGALTRADEMARKS2
VALUE "OriginalFilename", STR_ORIGINALFILENAME
VALUE "ProductName", STR_PRODUCTNAME
VALUE "ProductVersion", STR_PRODUCTVERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
为了完整起见,“.pro”文件中包含以下行:
RC_FILE = MyApp.rc
这一切似乎工作正常:当我右键单击 exe 并转到详细信息选项卡时,我可以看到版本信息和合并的 version.h 和 RC 文件中的所有其他字符串。
但是,如果我增加任何一个 VERSION_XXX #define 值并构建应用程序,我注意到报告的 "File version" 没有改变 - 只有当我执行"rebuild"版本有变化吗
我真的不想每次增加版本信息(目前主要是VERSION_BUILD)都必须完全重建,所以我需要做什么才能更新这些信息每次生成exe?
问题是 qmake
不支持 RC_FILE
的依赖项。那么对此可以做些什么呢?
1) 最简单和最快捷的方法是使用 touch
:如果 MyApp.rc
(几乎)永远不会改变,我们可以强制其时间戳遵循 version.h
之一。然后是这样的:
MyApp.pro
TARGET = MyApp
win*:RC_FILE = $${TARGET}.rc
win*:!build_pass:touch($$RC_FILE, version.h)
# ... more to follow
配合 qmake && make
就可以了。
2) 另一个看似简单的解决方案是 不 完全使用 RC_FILE
,但让 qmake
从预定义变量自动生成资源脚本:VERSION
、QMAKE_TARGET_COMPANY
、QMAKE_TARGET_DESCRIPTION
等。有关完整列表,请参阅 qmake Platform Notes。
只需将 VERSION = x.y.z.n
(并删除 RC_FILE = MyApp.rc
)添加到您的 .pro
文件即可启用此功能。
这对大多数 Qt 应用程序来说已经足够了,只要它们使用自己的 Qt 资源系统,而 Windows .rc 脚本只需要应用程序 ICON(s) 和 VERSIONINFO。
上面的例子:
version.pri
RC_ICONS = MyApp.ico
VERSION = 1.0.3.0
QMAKE_TARGET_COMPANY = MyCompany
QMAKE_TARGET_DESCRIPTION = MyFile
QMAKE_TARGET_COPYRIGHT = "Copyright © 2017 MyCompany"
QMAKE_TARGET_PRODUCT = MyApp
RC_CODEPAGE = 1252
RC_LANG = 0x0409
MyApp.pro
TARGET = MyApp
#win*:RC_FILE = $${TARGET}.rc
win*:include(version.pri)
# ... more to follow
不幸的是,这会带来另一个问题:如果您的 C++ 源代码树中仍然需要 version.h
,则必须以某种方式将其与 version.pri
同步。我认为使用 QMAKE_SUBSTITUTES
来自动生成 version.h
是最好的选择。不过加一堆DEFINES+=...
也是个思路。
3) 您可以在 .pro
文件中创建自定义目标并自行编译资源脚本。例如:
MyApp.pro
TARGET = MyApp
#win*:RC_FILE = $${TARGET}.rc
win* {
QMAKE_EXTRA_TARGETS += windows_resource
windows_resource.target = $${TARGET}_res$${first(QMAKE_EXT_OBJ)}
windows_resource.depends = $${TARGET}.rc version.h
msvc:windows_resource.commands = $$QMAKE_RC /fo $$windows_resource.target $${TARGET}.rc
else:windows_resource.commands = $$QMAKE_RC $${TARGET}.rc $$windows_resource.target
PRE_TARGETDEPS += $$windows_resource.target
LIBS += $$windows_resource.target
}
# ... more to follow
我的 Windows Qt 小部件应用程序使用 "version.h" 文件和 "RC" 文件来填充可执行文件的版本信息字符串。
version.h 看起来像这样...
#ifndef VERSION_H
#define VERSION_H
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_BUILD 3
#define VER_FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_BUILD,0
#define STR_FILEVERSION VERSION_MAJOR##"."##VERSION_MINOR##"."VERSION_BUILD##".0"
// Keep the product version as fixed
#define VER_PRODUCTVERSION 1.0.0.0
#define STR_PRODUCTVERSION "1.0.0.0[=11=]"
#define STR_COMPANYNAME "MyCompany"
#define STR_FILEDESCRIPTION "MyFile"
#define STR_INTERNALNAME "MyFile"
#define STR_LEGALCOPYRIGHT "Copyright © 2017 MyCompany"
#define STR_LEGALTRADEMARKS1 "All Rights Reserved"
#define STR_LEGALTRADEMARKS2 STR_LEGALTRADEMARKS1
#define STR_ORIGINALFILENAME "MyApp.exe"
#define STR_PRODUCTNAME "MyApp"
#define STR_COMPANYDOMAIN "mywebsite.com"
#endif // VERSION_H
RC 文件如下所示:
IDI_APP_ICON ICON DISCARDABLE "MyApp.ico"
#include <windows.h>
#include "version.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION
PRODUCTVERSION VER_PRODUCTVERSION
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
VALUE "CompanyName", STR_COMPANYNAME
VALUE "FileDescription", STR_FILEDESCRIPTION
VALUE "FileVersion", STR_FILEVERSION
VALUE "InternalName", STR_INTERNALNAME
VALUE "LegalCopyright", STR_LEGALCOPYRIGHT
VALUE "LegalTrademarks1", STR_LEGALTRADEMARKS1
VALUE "LegalTrademarks2", STR_LEGALTRADEMARKS2
VALUE "OriginalFilename", STR_ORIGINALFILENAME
VALUE "ProductName", STR_PRODUCTNAME
VALUE "ProductVersion", STR_PRODUCTVERSION
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1252
END
END
为了完整起见,“.pro”文件中包含以下行:
RC_FILE = MyApp.rc
这一切似乎工作正常:当我右键单击 exe 并转到详细信息选项卡时,我可以看到版本信息和合并的 version.h 和 RC 文件中的所有其他字符串。
但是,如果我增加任何一个 VERSION_XXX #define 值并构建应用程序,我注意到报告的 "File version" 没有改变 - 只有当我执行"rebuild"版本有变化吗
我真的不想每次增加版本信息(目前主要是VERSION_BUILD)都必须完全重建,所以我需要做什么才能更新这些信息每次生成exe?
问题是 qmake
不支持 RC_FILE
的依赖项。那么对此可以做些什么呢?
1) 最简单和最快捷的方法是使用 touch
:如果 MyApp.rc
(几乎)永远不会改变,我们可以强制其时间戳遵循 version.h
之一。然后是这样的:
MyApp.pro
TARGET = MyApp
win*:RC_FILE = $${TARGET}.rc
win*:!build_pass:touch($$RC_FILE, version.h)
# ... more to follow
配合 qmake && make
就可以了。
2) 另一个看似简单的解决方案是 不 完全使用 RC_FILE
,但让 qmake
从预定义变量自动生成资源脚本:VERSION
、QMAKE_TARGET_COMPANY
、QMAKE_TARGET_DESCRIPTION
等。有关完整列表,请参阅 qmake Platform Notes。
只需将 VERSION = x.y.z.n
(并删除 RC_FILE = MyApp.rc
)添加到您的 .pro
文件即可启用此功能。
这对大多数 Qt 应用程序来说已经足够了,只要它们使用自己的 Qt 资源系统,而 Windows .rc 脚本只需要应用程序 ICON(s) 和 VERSIONINFO。
上面的例子:
version.pri
RC_ICONS = MyApp.ico
VERSION = 1.0.3.0
QMAKE_TARGET_COMPANY = MyCompany
QMAKE_TARGET_DESCRIPTION = MyFile
QMAKE_TARGET_COPYRIGHT = "Copyright © 2017 MyCompany"
QMAKE_TARGET_PRODUCT = MyApp
RC_CODEPAGE = 1252
RC_LANG = 0x0409
MyApp.pro
TARGET = MyApp
#win*:RC_FILE = $${TARGET}.rc
win*:include(version.pri)
# ... more to follow
不幸的是,这会带来另一个问题:如果您的 C++ 源代码树中仍然需要 version.h
,则必须以某种方式将其与 version.pri
同步。我认为使用 QMAKE_SUBSTITUTES
来自动生成 version.h
是最好的选择。不过加一堆DEFINES+=...
也是个思路。
3) 您可以在 .pro
文件中创建自定义目标并自行编译资源脚本。例如:
MyApp.pro
TARGET = MyApp
#win*:RC_FILE = $${TARGET}.rc
win* {
QMAKE_EXTRA_TARGETS += windows_resource
windows_resource.target = $${TARGET}_res$${first(QMAKE_EXT_OBJ)}
windows_resource.depends = $${TARGET}.rc version.h
msvc:windows_resource.commands = $$QMAKE_RC /fo $$windows_resource.target $${TARGET}.rc
else:windows_resource.commands = $$QMAKE_RC $${TARGET}.rc $$windows_resource.target
PRE_TARGETDEPS += $$windows_resource.target
LIBS += $$windows_resource.target
}
# ... more to follow