如何停止Visual Studio 2015硬编码版本控制信息

6

我目前正在开发一个使用C++和VS2015的项目,该项目可以生成可执行文件。

我有一个名为version.h的文件,它简单地定义了一些数字。

#define VERSION_MAJOR               3
#define VERSION_MINOR               0
#define VERSION_REVISION            0
#define VERSION_BUILD               2
#define VER_FILE_VERSION            VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION, VERSION_BUILD
...

这个version.h文件用于项目的.rc文件中,定义可执行文件的版本信息。
.rc文件的格式如下:
#include "resource.h"
#include "version.h"
...
VS_VERSION_INFO VERSIONINFO
 FILEVERSION VER_FILE_VERSION
 ...

所以我的问题是,每次我添加一个资源并修改 resource.h 文件时,Visual Studio 2015 似乎会从 .rc 文件中删除 #include "version.h" 并且硬编码 "version.h" 中找到的所有值。
问题示例中的 .rc 文件:
#include "resource.h"
...
VS_VERSION_INFO VERSIONINFO
 FILEVERSION 3,0,0,2
 ...

所以我的问题是,我怎样才能阻止VS2015这样做?
1个回答

5

你无法阻止Visual Studio内置的资源编辑器这样做。每当你使用资源编辑器(即GUI)对资源文件中的项目进行更改时,它都会重新生成资源文件的代码。这将覆盖对资源文件进行的各种手动调整,包括用文字替换符号常量和/或算术、删除有条件定义的代码块、破坏仔细的手动格式等。因此,手动编辑资源文件不是一个好主意。

如果你需要能够对资源文件进行手动编辑而不被资源编辑器覆盖,那么你可以通过向项目添加第二个资源文件来实现。按照惯例,这个文件应该有一个.rc2扩展名。Visual Studio的资源编辑器永远不会直接编辑这些资源,这意味着所有的编辑必须手动完成。但是一旦你正确设置了它,你放置在那里的所有资源仍然会链接到你的二进制文件中,使最终结果等效。

这几乎是获得合理版本控制的唯一方法,我在自己的项目中使用它。例如:

//
// MyProj.RC2 - resources Microsoft Visual C++ does not edit directly
//

#ifdef APSTUDIO_INVOKED
   #error this file is not editable by Microsoft Visual C++
#endif  // APSTUDIO_INVOKED


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

#include "Version.h"


VS_VERSION_INFO VERSIONINFO
 FILEVERSION     VERSION_MYPROJ_MAJOR,VERSION_MYPROJ_MINOR,VERSION_MYPROJ_REVISION,0
 PRODUCTVERSION  VERSION_MYPROJ_MAJOR,VERSION_MYPROJ_MINOR,VERSION_MYPROJ_REVISION,0
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "040904b0"
        BEGIN
            VALUE "CompanyName", "Cody Gray"
            VALUE "FileDescription", "The World's Greatest Application"
            VALUE "FileVersion", VERSION_MYPROJ_FULL
            VALUE "InternalName", "MyProj"
            VALUE "LegalCopyright", "Copyrights are for suckers!"
            VALUE "OriginalFilename", "MyProj.exe"
            VALUE "ProductName", "MyProj"
            VALUE "ProductVersion", VERSION_MYPROJ_FULL
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x409, 1200
    END
END

你也可以在这里放置其他资源。例如,在我现在正在开发的一个应用程序中,我有一个对话框资源,我只想将其链接到“调试”构建中(它是用于配置内部调试相关选项的)。我尝试使用#ifdef DEBUG包装对话框的定义,但资源编辑器每次运行时都会剥离整个块,所以这是不可行的。相反,我将对话框的定义移动到了我的.rc2文件中,并将其保持在#ifdef中。我失去了使用资源编辑器编辑它的能力,但我并不太在意,因为在我需要进行更改的罕见情况下,我可以手动快速地进行编辑。至少它不会被自动剥离。

最后一个关键是让这个.rc2文件通过资源编辑器编译并链接到您的二进制文件中。为此,您需要编辑您的主资源文件(.rc),但这个更改将被保留。您要编辑的部分是TEXTINCLUDE资源。在我的.rc文件中,该部分看起来像这样:

/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "Resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""TargetVer.h""\r\n"
    "#endif\r\n"
    "#include ""AfxRes.h""\r\n"
    "#include ""VerRsrc.h""\r\n"
    "#include ""Version.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n"
    "LANGUAGE 9, 1\r\n"
    "#include ""MyProj.rc2""     // non-Microsoft Visual C++ edited resources\r\n"
    "#include ""AfxRes.rc""      // standard components\r\n"
    "#endif\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

重要的部分在于在第三个TEXTINCLUDE段中包含了MyProj.rc2。无论何时资源编译器运行,此处的任何文本都会直接转储到资源文件中,因此在您的资源文件末尾,您将会看到一个熟悉的自动生成的部分,例如:
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#include "MyProj.rc2"     // non-Microsoft Visual C++ edited resources
#include "AfxRes.rc"      // standard components
#endif

/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

值得一提的是,如果你无法从我的示例中搭配起来如何操作的话,Visual Studio 中的 MFC 项目模板可以自动为您完成此操作,如 这篇技术说明 所述。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接