还有比这更好的解决方案吗?
更好,我不知道,不同的是。
实际不需要 3rd 方工具。我们使用一个简单的脚本来执行此操作,并且从我记事起它就一直在运行(我认为是关于 Visual Studio 2010,从那时起进行了一些更改)。但是,您需要满足一些先决条件(但可以派上用场)。以下脚本应在 Visual Studio 2019/2017 和 PowerShell 3+ 中运行。
我们有一个文件version.h,如下所示:
#pragma once
#define VERSION_MAJOR 1
#define VERSION_MINOR 0
#define VERSION_PATCH 0
#define VERSION_BUILD 0
#define stringify(a) stringify_(a)
#define stringify_(a) #a
注意:version.h 需要在末尾换行以避免fatal error RC1004: unexpected end of file found。
资源文件可以包含头文件,因此在您的资源文件中包含version.h 并更改它以使用相应的定义:
#include "version.h"
// ... other stuff
VS_VERSION_INFO VERSIONINFO
FILEVERSION VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_BUILD
PRODUCTVERSION VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH, VERSION_BUILD
// ... other stuff
VALUE "FileVersion", stringify(VERSION_MAJOR) "." stringify(VERSION_MINOR) "." stringify(VERSION_PATCH) "." stringify(VERSION_BUILD)
VALUE "ProductVersion", stringify(VERSION_MAJOR) "." stringify(VERSION_MINOR) "." stringify(VERSION_PATCH) "." stringify(VERSION_BUILD)
// ... other stuff
现在在项目属性预构建脚本中,我们正在运行 PowerShell 脚本。命令:
powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"
脚本是一个查找和替换文本的增量:
(Get-Content -path $args[0] -Raw) |
ForEach-Object {
$defstr="#define VERSION_BUILD ";
$regex="$defstr(?<BuildVersion>\d*)";
if($_ -match $regex) {
$_ = $_ -replace $regex,"$($defstr)$(([int]$matches["BuildVersion"])+1)"
}
$_
} |
Out-File $args[0] -encoding ascii -nonewline
一些优点是:
-
version.h 是纯 C 语言,可以由任何符合 C/C++ 的编译器、MSVC 资源编译器甚至 Doxygen 等工具解析。
- 您可以在 C++ 文件中使用它:
#include "version.h"
int main() {
std::cout << "Hello World Version " stringify(VERSION_MAJOR) "." stringify(VERSION_MINOR) "." stringify(VERSION_PATCH) "." stringify(VERSION_BUILD) " !\n";
}
- 版本控制是集中的
- 处理主要/次要/补丁版本的其他脚本也很简单
- 脚本比较简单,维护也很简单