Mecanik
Mecanik

Reputation: 1059

Auto increment FileVersion (build nr) in Visual Studio 2019

After a lot of searching I found a tool to track and increment projects build nr. for c/c++ projects. All the others are either outdated or for C#.

I'm using IncrementBuild-*.exe from this blog: http://alax.info/blog/1713

It works as expected but I believe I`m doing something wrong because after running this tool post build it adds another VERSIONINFO resource for some reason. The project ends up having 2 resources, the original and the patched one.

There is no source code or .pdb to modify/remake/analyse this.

Does anyone have a better solution than this ?

Please advise, much appreciated.

Upvotes: 1

Views: 4490

Answers (1)

user1810087
user1810087

Reputation: 5334

Does anyone have a better solution than this ?

Better, I don't know, different yes.
There is no actual need for a 3rd party tool. We use a simple script for doing this and it was running since I can remember (about Visual Studio 2010 I think, with some changes since back then). However, you need to fulfill some prerequisites (but which can come in handy). The script below should run in Visual Studio 2019/2017 and PowerShell 3+.

We have a file version.h which looks like this:

#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

Note: version.h requires a new line at the end to avoid fatal error RC1004: unexpected end of file found.

Resource files can include header files, and therefore include version.h in your resource file and change it to use the defines accordingly:

#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

Now in the project properties pre-build scripts we are running a PowerShell script. The command:

powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"

And the script is a find & replace text with an increment:

(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

Some advantages are:

  • version.h is plain C and can be parsed by any C/C++-compliant compiler, MSVC resource compiler or even tools like Doxygen.
  • You can use it in your C++ files:
#include "version.h"
int main() {
    std::cout << "Hello World Version " stringify(VERSION_MAJOR) "." stringify(VERSION_MINOR) "." stringify(VERSION_PATCH) "." stringify(VERSION_BUILD) " !\n";
}
  • versioning is centralized
  • other scripts to handle major/minor/patch versions are also simple
  • the scripts are fairly simple, and maintenance is also simple

Upvotes: 8

Related Questions