Visual C++ doesn’t have a feature to automatically increment the version resource
information of your project after each build.
This article describes one way to provide such a feature.
You can write a program to modify the resource compiler (.rc) file instead of
using the steps described here. However, the RC file is under the control of
Visual C++. Visual C++ modifies the RC file while saving, and this may affect
the version resource. The approach described in this section can be applied to
any Visual C++ project. This example uses a Microsoft Foundation Classes
project.
Create a new project using the MFC (EXE) Appwizard and call it
MyProject . MyProject will have a MyProject.rc file,
which includes MyProject.rc2. The .rc2 file is meant for user-defined resources.
Follow these steps to increment MyProject’s version information after each
build:
- Remove the version resource from the .rc file and place it in the .rc2
file:
- Open both MyProject.rc and MyProject.rc2 (found in the Res folder),
in a text editor. To use the Visual C++ editor, click Open on the
File menu and select Text in the Open As list for the
MyProject.rc file. - Find the version resource statements in MyProject.rc. It should look
something like:01
///
02
//
03
// Version
04
//
05
06
VS_VERSION_INFO VERSIONINFO
07
FILEVERSION 1,0,0,1
08
PRODUCTVERSION 1,0,0,1
09
FILEFLAGSMASK 0×3fL
10
#ifdef _DEBUG
11
FILEFLAGS 0×1L
12
#else
13
FILEFLAGS 0×0L
14
#endif
15
FILEOS 0×4L
16
FILETYPE 0×1L
17
FILESUBTYPE 0×0L
18
BEGIN
19
BLOCK
"StringFileInfo"
20
BEGIN
21
BLOCK
"040904b0"
22
BEGIN
23
VALUE
"Comments"
,
"Sample Application/0"
24
VALUE
"CompanyName"
,
"Microsoft Corp./0"
25
VALUE
"FileDescription"
,
"MyProject MFC Application/0"
26
VALUE
"FileVersion"
,
"1, 0, 0, 1/0"
27
VALUE
"InternalName"
,
"MyProject/0"
28
VALUE
"LegalCopyright"
,
"Copyright (C) 1999/0"
29
VALUE
"OriginalFilename"
,
"MyProject.EXE/0"
30
VALUE
"ProductName"
,
"MyProject Application/0"
31
VALUE
"ProductVersion"
,
"1, 0, 0, 1/0"
32
END
33
END
34
BLOCK
"VarFileInfo"
35
BEGIN
36
VALUE
"Translation"
, 0×409, 1200
37
END
38
END
- Cut the version resource from the MyProject.rc file and paste it into
the MyProject.rc2 file below the comment “Add manually edited resources here.”
For information about what each one of the fields in the resource means, see the
VERSIONINFO resource statement in Help.
- Replace the FILEVERSION and PRODUCTVERSION data with macros FILEVER and
PRODUCTVER. Similarly, replace the FileVersion and ProductVersion string data
with the macros STRFILEVER and STRPRODUCTVER. - Add a #include VersionNo.h immediately before
the VS_VERSION_INFO resource statement. Now the version resource will look like:01
///
02
//
03
// Version
04
//
05
#include "VersionNo.h"
06
VS_VERSION_INFO VERSIONINFO
07
FILEVERSION FILEVER
08
PRODUCTVERSION PRODUCTVER
09
FILEFLAGSMASK 0x3fL
10
#ifdef _DEBUG
11
FILEFLAGS 0x1L
12
#else
13
FILEFLAGS 0x0L
14
#endif
15
FILEOS 0x4L
16
FILETYPE 0x1L
17
FILESUBTYPE 0x0L
18
BEGIN
19
BLOCK
"StringFileInfo"
20
BEGIN
21
BLOCK
"040904b0"
22
BEGIN
23
VALUE
"Comments"
,
"Sample Application/0"
24
VALUE
"CompanyName"
,
"Microsoft Corp./0"
25
VALUE
"FileDescription"
,
"MyProject MFC Application/0"
26
VALUE
"FileVersion"
, STRFILEVER
27
VALUE
"InternalName"
,
"MyProject/0"
28
VALUE
"LegalCopyright"
,
"Copyright (C) 1997/0"
29
VALUE
"OriginalFilename"
,
"MyProject.EXE/0"
30
VALUE
"ProductName"
,
"MyProject Application/0"
31
VALUE
"ProductVersion"
, STRPRODUCTVER
32
END
33
END
34
BLOCK
"VarFileInfo"
35
BEGIN
36
VALUE
"Translation"
, 0x409, 1200
37
END
38
END
- Create a header file called VersionNo.h in the same directory as your
project. This file will contain the following statements, which are the
definitions for macros used in step 2:1
#define FILEVER 1,0,0,1
2
#define PRODUCTVER 1,0,0,1
3
#define STRFILEVER “1, 0, 0, 1/0″
4
#define STRPRODUCTVER “1, 0, 0, 1/0″
NOTE: Add linefeed and carriage return characters on the last line.
Now, MyProject.rc file includes MyProject.rc2, and MyProject.rc2 file includes VersionNo.h. - The VersionNo.h file contents will be modified using a Visual Basic Script
macro. The macro described below handles the Visual C++ BuildFinish event, so it
will not be fired until a build completes. Whenever this VB Script code is
called, it first increments the version numbers inside the header file by a
fixed amount, then it saves the file and closes it. During a subsequent build,
the new version number is included in the executable.
To install and use
the VB Script code, do the following:
- Open an existing DSM (macro) file or create a new DSM file in Visual
C++. To create a new file, click New on the File menu, select
Macro File on the Files tab, give it a name, and click OK . - Paste the following VB Script code below (an empty DSM file cannot be
installed in Visual C++; the next step explains installing):01
Function
GetProjectDir(FullName)
02
03
'VC++ doesn't provide any method for getting the path of the active project
04
'See the VB Script reference for more information on the VB Script functions
05
'used in this function
06
07
Dim
proj_path
08
proj_path = Split(StrReverse(FullName),"/",-1,1)
09
10
Dim
count
11
count = UBound(proj_path)
12
13
Dim
full_path
14
full_path =
""
15
Dim
i
16
17
for i = 1 to count
18
full_path = full_path & "/" & proj_path(i)
19
next
20
21
GetProjectDir = StrReverse(full_path)
22
End
Function
23
24
Sub
ReplaceText(selection, count, incrementby)
25
26
'selection represents the TextSelection object
27
'count represents the position of the version number to be incremented
28
'incrementby represents a number that will be added to the existing version number
29
30
selection.WordRight dsMove, count
31
selection.WordRight dsExtend, 1
32
Dim
str
33
str = selection.Text
34
str = str + incrementby
35
36
selection.Text = str
37
38
End
Sub
39
40
Sub
Application_BuildFinish(numError, numWarning)
41
42
'This event will be triggered after every build of a project
43
'You can check numError and/or numWarning to determine if you want to continue
44
'If numError <> 0 Then
45
'exit sub
46
'Obtain the full path of the active project
47
Dim
full_path
48
full_path = GetProjectDir(ActiveProject.FullName)
49
50
full_path = full_path &
"versionno.h"
51
52
'Open the VersionNo.h file
53
Documents.Open full_path
54
55
'Obtain the TextSelection object
56
Dim
selection
57
set selection = ActiveDocument.Selection
58
selection.StartOfDocument
59
60
'Increment the version information
61
ReplaceText selection, 9, 1
62
selection.LineDown
63
selection.StartOfLine
64
ReplaceText selection, 9, 1
65
selection.LineDown
66
selection.StartOfLine
67
ReplaceText selection, 10, 1
68
selection.LineDown
69
selection.StartOfLine
70
ReplaceText selection, 10, 1
71
72
ActiveDocument.Save
73
ActiveDocument.Close
74
End
Sub
NOTE: This code is an unsupported sample. You may modify it for your build scenario.
- Install the DSM file if it is not already installed. To install,
click Customize on the Tools menu, click the Add-in and Macro
Files tab, browse to select the DSM file, and click Close .
- Select Build MyProject.exe from the Build menu. After the
build finishes, open the VersionNo.h file. It will contain the following
statements:1
#define FILEVER 1,0,0,2
2
#define PRODUCTVER 1,0,0,2
3
#define STRFILEVER "1, 0, 0, 2/0"
4
#define STRPRODUCTVER "1, 0, 0, 2/0"
If you build the code again, this version information in included in the executable,
and the version information is incremented.
You can introduce some code in the macro described earlier to
prevent incrementing version numbers if the build produced errors.