msbuildresourcebundleversioninfo

How to inject the right version information into the resources at compile time?


I was surprised to discover that apparently it is not possible to import C predefined macros inside the resource files (.rc) because Resource Compiler is not able to deal with them.

I was trying to put the version information inside a version.h that would be generated / updated by the build system. This file was supposed to be included from the resource.rc so when you build the resources you will always get the same versions across all the built files.

It seems that this has something to do with RC_INVOKED and this bug http://connect.microsoft.com/VisualStudio/feedback/details/532929/rc4011-warnings-from-vc10-rc -- which is closed as "as-designed".

How can I solve this problem?

Is the only option to patch the final exe in order to update the version information? ... I would prefer not do to this and use a more standard way for this.


Solution

  • The resource compiler deals just fine with includes and preprocessor definitions. It just does not deal well with including Windows.h for instance. But I cannot think of any good reason why you'd need that in a file that gets consumed by the resource compiler. Just use a header file that does not include anything causing the warning, and just define what you need. As an example the typical versioning we use here does this and works great: there's a single master .rc file with that looks something like this:

    #include <winver.h>
    
    #define stringize( x )        stringizei( x )
    #define stringizei( x )       #x
    
    #ifdef VRC_INCLUDE
      #include stringize( VRC_INCLUDE )
    #endif
    
    #ifdef _WIN32
      LANGUAGE 0x9,0x1
      #pragma code_page( 1252 )
    #endif
    
    1 VERSIONINFO
     FILEVERSION    VRC_FILEVERSION
     PRODUCTVERSION VRC_PRODUCTVERSION
     FILEFLAGSMASK  0x1L
     FILEFLAGS      VS_FF_DEBUG
     FILEOS         VOS__WINDOWS32
     FILETYPE       VRC_FILETYPE
    BEGIN
      BLOCK "StringFileInfo"
      BEGIN
        BLOCK "040904E4"
        BEGIN
          VALUE "CompanyName",      stringize( VRC_COMPANYNAME )
          VALUE "FileDescription",  stringize( VRC_FILEDESCRIPTION )
          VALUE "FileVersion",      stringize( VRC_FILEVERSION )
          VALUE "LegalCopyright",   stringize( VRC_COPYRIGHT )
          VALUE "InternalName",     stringize( VRC_ORIGINALFILENAME )
          VALUE "OriginalFilename", stringize( VRC_ORIGINALFILENAME )
          VALUE "ProductName",      stringize( VRC_PRODUCTNAME )
          VALUE "ProductVersion",   stringize( VRC_PRODUCTVERSION )
        END
      END
      BLOCK "VarFileInfo"
      BEGIN
        VALUE "Translation", 0x409, 1200
      END
    END
    

    From here on the possibilities are pretty much unlimited. Either define VRC_INCLUDE to the full path of an include file containing all the VRC_... definitions:

    rc /d VRC_INCLUDE=$(VersionMainInclude) ... version.rc

    or supply all definitions

    rc /d VRC_COMPANYNAME=mycompany ... version.rc

    or a combination of both.

    To show you the possibilities, here's what I'm currently doing for all projects versioned with git: