在软件开发过程中,产品版本控制是一个至关重要的环节。它不仅帮助追踪产品的不同发布版本,还为市场支持提供了基准。例如,有一个名为“二进制版本工具”的产品,其市场发布版本(RTM)为2.0。这个版本号为提供了一个明确的参考点,以识别市场上需要支持的版本。每当客户报告问题时,也会根据产品版本来识别问题,因为一个版本的bug可能在另一个版本中并不存在。
产品版本控制对于确定公司名称和产品的法律版权也至关重要,这有助于确认产品的所有权。此外,当谈论一个产品时,它通常包含多个组件,因此需要为每个组件维护这些信息。对于某些产品来说,可能包含10个组件,而对于其他产品,组件数量可能超过100个。因此,维护产品版本控制变得非常关键,而且这个过程需要简单且稳定。
在阅读完本文后,应该能够轻松地维护产品版本。对于VC项目(例如Win32/MFC/ATL/COM),通常会在资源文件(rc文件)中更新版本信息。每当组件版本更新时,也会更新这个rc文件。
在版本控制中,有一些信息是所有组件共有的,比如产品名称、公司名称和法律版权。每次为每个新组件添加这些信息并不是一个好主意。应该将这些信息放在一个公共位置,然后在这些rc文件中使用。
考虑这样一个场景:计划重振产品并更改产品名称。假设产品名称从“网络管理器”更改为“开放网络管理器”。在这种情况下,需要更新产品中每个rc文件。这可能会很痛苦,出错的机会也很高。如果只需要在一个位置进行更新,那将会更加顺利。对于公司名称的更改也是如此,一个非常常见的原因是收购。
让从一个名为“二进制版本工具”的产品的小例子开始,该产品包含三个名为TestApp1、TestApp2和TestApp3的组件。这三个组件都将拥有自己的资源文件,用于版本控制,需要更新以维护产品和各个组件的完整版本信息。
步骤1:创建一个包含版本信息的公共头文件
让开始创建一个名为CommonVer.h的公共头文件,并包含以下信息:
#define PRODUCT_NAME "二进制版本工具"
#define PRODUCT_VER_VAL 5,0,0,0
#define PRODUCT_VER_STR "5.0.0.0\\0"
#define COMPANY_NAME "公司"
#define LEGAL_COPYRIGHT "版权所有 (C) 2013 公司."
PRODUCT_VER_VAL和PRODUCT_VER_STR包含相同的信息,但格式不同,这是rc文件理解版本信息的方式。随着通过示例的进行,这一点将变得更加清晰。
步骤2:向头文件添加每个组件的信息
#define TESTAPP1_VERSION_VAL 1,0,0,0
#define TESTAPP1_VERSION_STR "1.0.0.0\\0"
#define TESTAPP1_FILE_DESC "这是测试应用程序1"
#define TESTAPP1_FILE_NAME "TestApp1.exe"
#define TESTAPP2_VERSION_VAL 2,0,0,0
#define TESTAPP2_VERSION_STR "2.0.0.0\\0"
#define TESTAPP2_FILE_DESC "这是测试应用程序2"
#define TESTAPP2_FILE_NAME "TestApp2.exe"
#define TESTAPP3_VERSION_VAL 3,0,0,0
#define TESTAPP3_VERSION_STR "3.0.0.0\\0"
#define TESTAPP3_FILE_DESC "这是测试应用程序3"
#define TESTAPP3_FILE_NAME "TestApp3.exe"
步骤3:为每个组件更新单独的rc文件
现在打开TestApp1的rc文件,如下所示:
在rc文件的开头添加公共头文件:
#include "CommonVer.h"
转到版本部分,并使用在CommonVer.h中创建的宏进行更新:
VS_VERSION_INFO VERSIONINFO
FILEVERSION TESTAPP1_VERSION_VAL
PRODUCTVERSION PRODUCT_VER_VAL
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK
"StringFileInfo"
BEGIN
BLOCK
"040904b0"
BEGIN
VALUE
"CompanyName"
, COMPANY_NAME
VALUE
"FileDescription"
, TESTAPP1_FILE_DESC
VALUE
"FileVersion"
, TESTAPP1_VERSION_STR
VALUE
"InternalName"
, TESTAPP1_FILE_NAME
VALUE
"LegalCopyright"
, LEGAL_COPYRIGHT
VALUE
"OriginalFilename"
, TESTAPP1_FILE_NAME
VALUE
"ProductName"
, PRODUCT_NAME
VALUE
"ProductVersion"
, PRODUCT_VER_STR
END
END
BLOCK
"VarFileInfo"
BEGIN
VALUE
"Translation"
,
0x409
,
1200
END
END
#endif // English (United States) resources
步骤4:验证更改
现在,已经准备好了CommonVer.h和rc文件。同样,可以为其他组件添加更改。现在,一切都可以从一个位置轻松控制,即CommonVer.h。
假设想要更新产品和组件的版本。只需更新以下宏即可完成!!!
#define PRODUCT_VER_VAL 6,0,0,0
#define PRODUCT_VER_STR "6.0.0.0\\0"
#define TESTAPP1_VERSION_VAL 2,0,0,0
#define TESTAPP1_VERSION_STR "2.0.0.0\\0"
相同的更改可以通过打开rc文件的GUI进行验证。之后,可以构建二进制文件,它将在详细信息标签中看起来像这样。
如今,应用程序架构变得非常重要,因为每个产品都有其32位和64位版本。一旦构建了二进制文件,就需要相应地打包,以便将其运送到特定平台。
很多时候,开发人员或集成人员会因为复制了错误的架构二进制文件而遇到麻烦,例如:为32位系统打包64位二进制文件,最终在测试或QA甚至有时是客户问题中看到失败。这是因为没有更容易的方法通过查看二进制文件的属性来识别二进制文件的架构。
通常,如果是开发人员,会运行像“DumpBin”这样的工具来识别二进制文件的架构,但这也需要一定的努力。如果能在二进制文件的属性中,即在详细信息标签中获得这些信息,那就太好了。
让回到公共代码,即CommonVer.h。
#define TESTAPP1_FILE_DESC "这是测试应用程序1"
在这里,可以在描述本身中添加二进制文件的架构。但是,对于32位和64位版本,这必须有所不同。按照以下步骤实现这一点。
步骤1:添加WIN64宏
按照以下步骤添加WIN64宏:
从配置管理器添加x64配置
选择配置为x64
在rc文件的预处理器中添加64位宏,如下所示:
步骤2:更新公共头文件
在CommonVer.h中添加以下代码:
#ifdef WIN64
#define TESTAPP1_FILE_DESC "这是测试应用程序1 (64位)"
#else
#define TESTAPP1_FILE_DESC "这是测试应用程序1 (32位)"
#endif
步骤3:验证输出
现在为64位构建应用程序,输出应该是这样的:
现在为32位构建应用程序,输出应该是这样的:
现在,通过检查其属性,可以很容易地识别二进制文件的架构。
按照这三个简单的步骤将当前产品的版本信息迁移到一个单一的头文件:
1. 确定产品的所有组件
2. 创建一个公共版本头文件,它将维护所有组件的信息
3. 使用公共头文件中定义的宏更新所有组件的rc文件
一旦代码使用公共版本控制机制进行迁移,通过RC编辑器UI更新版本,将抹去所做的所有更改。可以使用RC编辑器查看更改,但不应进行编辑,版本应该只通过头文件更新。