如何在编译时将正确的版本信息注入资源?

时间:2013-07-29 16:02:45

标签: msbuild resourcebundle versioninfo

我很惊讶地发现显然无法在资源文件(.rc)中导入C预定义宏,因为资源编译器无法处理它们。

我试图将版本信息放在由构建系统生成/更新的version.h中。该文件应该包含在resource.rc中,因此在构建资源时,您将始终在所有构建的文件中获得相同的版本。

这似乎与RC_INVOKED和此错误http://connect.microsoft.com/VisualStudio/feedback/details/532929/rc4011-warnings-from-vc10-rc有关 - 它被关闭为“按设计”。

我该如何解决这个问题?

是唯一可以修补最终exe以更新版本信息的选项吗? ...我不想这样做,并采用更标准的方式。

1 个答案:

答案 0 :(得分:2)

资源编译器可以很好地处理包含和预处理器定义。例如,包括Windows.h在内的情况并不好。但我想不出任何为什么你需要在资源编译器消耗的文件中使用它的好理由。只需使用不包含导致警告的任何内容的头文件,只需定义您需要的内容即可。作为一个例子,我们在这里使用的典型版本控制实现了这个并且效果很好:有一个单个主.rc文件,看起来像这样:

#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

从这里开始,可能性几乎是无限的。将VRC_INCLUDE定义为包含所有VRC_...定义的包含文件的完整路径:

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

或提供所有定义

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

或两者兼而有之。

为了向您展示可能性,以下是我目前正在为使用git进行版本化的所有项目所做的事情:

  • 每个项目都有一个version.h #defining只是一个简短的VRC_FILEDESCRIPTION和VRC_FILEVERSION
  • 有一个主版本.h #defining VRC_COMPANYNAME / VRC_COPYRIGHT /...
  • 该项目包含一个.targets文件,该文件在预建事件中创建一个version.res
  • msbuild prebuild事件处理有趣的事情:它创建一个新的临时头文件,结合其他两个,获取短git SHA和当前数据,并将其附加到文件描述字符串,以便它最终看起来像

    Foo Dll [12e454re 30/07/2013]