The_Cartographer
The_Cartographer

Reputation: 77

How can I modify VS_VERSION_INFO from the cpp file

When I go to Resource View -> myproject.rc -> Version -> VS_VERSION_INFO I've got the fields I can change. It is possible to change these fields through cpp file? so I could use something like:

#define FileDescription "This is my program"

That would be cool because it's annoying to always go there and change these fields.

Upvotes: 5

Views: 11377

Answers (5)

user2985792
user2985792

Reputation:

Create a file in your project called "filever.rc2", for example.

filever.rc2 should look like this:

#include "version.h"


/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION VER_FILE_VERSION
 PRODUCTVERSION VER_PRODUCT_VERSION
 FILEFLAGSMASK 0x3fL
 FILEFLAGS VER_FILEFLAGS
 FILEOS VER_FILEOS
 FILETYPE VER_FILETYPE
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "CompanyName", VER_COMPANY_STR "\0"
            VALUE "FileDescription", "Your Application"
            VALUE "FileVersion", VER_FILE_VERSION_STR "\0"
            VALUE "InternalName", "Your"
            VALUE "LegalCopyright", VER_COPYRIGHT_STR "\0"
            VALUE "LegalTrademarks", VER_TRADEMARK_STR "\0"
            VALUE "OriginalFilename", "Your.exe"
            VALUE "ProductName", "Your Application"
            VALUE "ProductVersion", VER_PRODUCT_VERSION_STR "\0"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

The information in 'filever.rc2' was copied and pasted out of the existing auto-generated .rc file for the project. Then it was modified to use the defined identifiers. The #include "version.h" will be where the defines come from. This file can be part of your application, where you can modify the version information from visual studio.

In the file "version.h", add things like:

#define VERSION_YEAR        16  // 2 digit year
#define VERSION_MONTH       4   // 2 digit month
#define VERSION_DAY         22  // 2 digit day
#define VERSION_UNSAFE      0   // 0 = TESTED, 1 = UNSAFE / IN DEVELOPMENT

#define VER_COPYRIGHT_STR       "Copyright (C) 1999 - 2016"
#define VER_TRADEMARK_STR       "Your Trademark"
#define VER_COMPANY_STR     "Your Company"

#define STRINGIZE2(s)               #s
#define STRINGIZE(s)                STRINGIZE2(s)
#if (VERSION_UNSAFE == 1)
    #define MY_VERSION_NUM          STRINGIZE(VERSION_YEAR) STRINGIZE(VERSION_MONTH) "." STRINGIZE(VERSION_DAY) STRINGIZE(VERSION_UNSAFE)
#else
    #define MY_VERSION_NUM          STRINGIZE(VERSION_YEAR) STRINGIZE(VERSION_MONTH) "." STRINGIZE(VERSION_DAY)
#endif
#define VER_FILE_VERSION            VERSION_YEAR, VERSION_MONTH, VERSION_DAY, VERSION_UNSAFE
#define VER_FILE_VERSION_STR        STRINGIZE(VERSION_YEAR) "." STRINGIZE(VERSION_MONTH) "." STRINGIZE(VERSION_DAY) "." STRINGIZE(VERSION_UNSAFE)
#define VER_PRODUCT_VERSION         VER_FILE_VERSION
#define VER_PRODUCT_VERSION_STR     VER_FILE_VERSION_STR
#ifdef _DEBUG
    #define VER_VER_DEBUG           VS_FF_DEBUG
#else
    #define VER_VER_DEBUG           0
#endif
#define VER_FILEOS                  VOS_NT_WINDOWS32
#define VER_FILEFLAGS               VER_VER_DEBUG
#define VER_FILETYPE                VFT_APP

Now, go to the resource browser, and right click on the resource folder for the project you are working on. Click on "resource includes".

Add:

#include "filever.rc2" to the list of includes under "Read-only symbol directives".

This will get the filever.rc2 file included into the resource file. Click OK. There will be a warning about making the change. Hit ok to go on and make the change.

Now, browse to the "Version" folder in the resource file. Open that folder, right click on the version entry, and select delete to delete the version entry. If it is not deleted, there will be a duplicate resource, because we added the same information in the filever.rc2 file, which we are including.

The version information is now going to be using the included version that is in filever.rc2. This way it will not be auto-generated away, which would be the case if it is in the project resource file.

From then forward, when you change the constants in version.h and build, the version information embedded into your executable will come from the version.h file.

This solution is an example of what was described in earlier posts. Hopefully this clarifies how to implement what was suggested.

I am not sure that there is anything magic about the '.rc2' extension on the filever.rc2 file, but I found out by experimentation that if you call it .rc it appears in the resource browser and that is not really desirable. If you call it .h, it doesn't edit well in visual studio because it tries to intellisense it and it mostly looks like errors. Calling it .rc2 seemed to make everyone happy and not cause side effects.

Cheers.

Upvotes: 9

jhole
jhole

Reputation: 4226

Just include the header containing your infos in the rc file:

version1.h:

#define RELEASE_VER 1 // 0: beta version; 1: release version
#define RELEASE_DATE "May 09 2013" // Mmm dd yyyy; only used for RELEASE_VER=1

#define RELEASE_VER_MAIN  3 // version number (binary)
#define RELEASE_VER_MAIN2 0
#define RELEASE_VER_SUB   4
#define RELEASE_VER_SUB2  0

// version number (string)
#define TOSTRING2(arg) #arg
#define TOSTRING(arg) TOSTRING2(arg)
#define RELEASE_VER_STR     TOSTRING(RELEASE_VER_MAIN)"."TOSTRING(RELEASE_VER_MAIN2)"."\
                        TOSTRING(RELEASE_VER_SUB)"."TOSTRING(RELEASE_VER_SUB2)

myapp.rc

#include "winver.h"
#include "../../core/version1.h"

/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
1           ICON         "mayapp.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Version
//

1 VERSIONINFO
 FILEVERSION RELEASE_VER_MAIN,RELEASE_VER_MAIN2,RELEASE_VER_SUB,RELEASE_VER_SUB2
 PRODUCTVERSION RELEASE_VER_MAIN,RELEASE_VER_MAIN2,RELEASE_VER_SUB,RELEASE_VER_SUB2
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS VOS_NT_WINDOWS32
 FILETYPE VFT_APP
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
    BEGIN
        VALUE "Comments", "\0"
        VALUE "CompanyName", "Developed by xxx\0"
        VALUE "FileDescription", "mayapp super\0"
        VALUE "FileVersion", RELEASE_VER_STR
        VALUE "InternalName", "mayapp\0"
        VALUE "LegalCopyright", "Copyright (c) by my\0"
        VALUE "LegalTrademarks", "\0"
        VALUE "OriginalFilename", "mayapp\0"
        VALUE "PrivateBuild", "\0"
        VALUE "ProductName", "mayapp\0"
        VALUE "ProductVersion", RELEASE_VER_STR
        VALUE "SpecialBuild", "\0"
    END
END
BLOCK "VarFileInfo"
BEGIN
    VALUE "Translation", 0x409, 1200
END
END

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941218

You can't. The version resource is embedded into your EXE by the linker, it isn't a variable. Windows knows how to find it and display the version in the Properties window. Trying to modify it with your code isn't useful by design, it isn't running when the user looks at the properties. Nor can you modify your own EXE file, it is locked while your program is running. And UAC stops programs from tinkering with executables, the iceberg that sinks Roman's approach.

You don't have to use the resource editor if it annoys you, the .rc file is just a text file that you can edit with a text editor, just like your .cpp source code. And the preprocessor gets a shot at the file first, you can substitute strings so just editing a .h file that the .rc file #includes gets the job done too.

Upvotes: 2

Roman Ryltsov
Roman Ryltsov

Reputation: 69632

You can modify resources on already built binary using BeginUpdateResource, UpdateResource, EndUpdateResource API.

If you want to automate the updates, another option is to use this tool that wraps API mentioned above and exposes script-friendly COM interfaces.

Image = new ActiveXObject(“AlaxInfoResourceTools.Image”);
Image.Initialize(“C:\\Sample.dll”);
WScript.Echo(“Product Version: ” + Image.VersionInfo.ProductVersionString);
WScript.Echo(“File Version: ” + Image.VersionInfo.FileVersionString);
var ProductName = Image.VersionInfo.GetString(0, “ProductName”);
var OemProductName = Image.VersionInfo.GetString(0, “OemProductName”);
WScript.Echo(“ProductName: ” + ProductName);
WScript.Echo(“OemProductName: ” + OemProductName);
Image.VersionInfo.SetString(0, “OemProductName”, “// ” + ProductName);
Image.VersionInfo.Update();
Image.EndUpdate(false);

If you are building yourself, then the easiest if certainly to modify resource scripts directly, either using IDE editors, or directly in .rc file(s).

Upvotes: 0

Bathsheba
Bathsheba

Reputation: 234635

You can edit the resource files .rc and resource.h files directly in the text editor. But close the resource viewer down first though.

Upvotes: 3

Related Questions