C++ 如何同步EXE/DLL文件的SVN修订版和版本资源?

C++ 如何同步EXE/DLL文件的SVN修订版和版本资源?,c++,svn,resources,build-automation,C++,Svn,Resources,Build Automation,如果您安装了OrtoiseSVN,则会安装一个程序,SubWCRev 如果您的文件中有以下值: $WCREV$ 然后,如果执行以下操作,它将被替换为最高的提交修订号: SubWCRev .\ yourfile.txt.template yourfile.txt 这将从yourfile.txt.template复制,进行替换,然后写入yourfile.txt 请注意,您还可以使用许多其他宏,如果您在不带任何参数的情况下执行SubWCRev,它将在控制台上列出所有宏。您可能需要查看和。它们不能解

如果您安装了OrtoiseSVN,则会安装一个程序,
SubWCRev

如果您的文件中有以下值:

$WCREV$
然后,如果执行以下操作,它将被替换为最高的提交修订号:

SubWCRev .\ yourfile.txt.template yourfile.txt
这将从
yourfile.txt.template
复制,进行替换,然后写入
yourfile.txt


请注意,您还可以使用许多其他宏,如果您在不带任何参数的情况下执行
SubWCRev
,它将在控制台上列出所有宏。

您可能需要查看和。它们不能解决资源问题,因为它们总是包含该死的
$KeywordName:…$
部分自定义属性确实提供了一种很好的方法,可以使元数据在批处理文件或其他文件中可用

不管怎样,几年前我一直在寻找解决资源问题的方法,但没有找到。因此,我们创建了自己的自主解决方案。我们将RC文件更改为包含在构建过程中生成的头文件。RC依赖于标头,标头有一个自定义生成规则,该规则调用批处理文件来生成标头。以下代码段将从
svn info
的输出中提取当前版本

SET rootdir=%1
SET svnrev=0
PUSHD "%rootdir%"
FOR /F "tokens=1-4 delims=: " %%I IN ('svn info') DO (
    IF /I {%%I}=={rev} SET svnrev=%%L
)
(ECHO./*
 ECHO. * version-stamp.h - repository version information
 ECHO. */
 ECHO.#ifndef VERSION_STAMP_H
 ECHO.#define VERSION_STAMP_H
 ECHO.#define REPOSITORY_VERSION %svnrev%
 ECHO.#endif) > include\version-stamp.h
POPD
然后,我们创建了一个名为
component info.h
的特定于组件的版本戳头,它看起来像:

#ifndef component_info_h
#define component_info_h
#include "product-info.h"
#include "version-stamp.h"

#define VERS_MAJOR 1
#define VERS_MINOR 2
#define VERS_PATCH 3
#define VERS_BUILD REPOSITORY_VERSION

#define MY_COMPONENT_NAME "TPS Report Generator"    
#define MY_VERSION_NUMBER VERS_MAJOR,VERS_MINOR,VERS_PATCH,VERS_BUILD
#define MY_VERSION_STRING VERSION_STRING(VERS_MAJOR,VERS_MINOR,VERS_PATCH,VERS_BUILD)

#endif
最后,我们有一个产品线版本文件,它定义了名为
product info.h
的产品信息:

#ifndef product_info_h
#define product_info_h

#define PROD_VERS_MAJOR 0
#define PROD_VERS_MINOR 1
#define PROD_VERS_PATCH 0
#define PROD_VERS_BUILD 0

#define VSTR1(s) #s
#define VSTR(s) VSTR1(s)
#define VERSION_STRING(a,b,c,d) VSTR(a) "." VSTR(b) "." VSTR(c) "." VSTR(d) "\0"

#define MY_COMPANY_NAME         "IniTech\0"
#define MY_COPYRIGHT            "Copyright ©2009 " MY_COMPANY_NAME
#define MY_PRODUCT_NAME         "\0"
#define MY_PRODUCT_VERSION_NUM  PROD_VERS_MAJOR,PROD_VERS_MINOR,PROD_VERS_PATCH,PROD_VERS_BUILD
#define MY_PRODUCT_VERSION_STR  VERSION_STRING(PROD_VERS_MAJOR,PROD_VERS_MINOR,PROD_VERS_PATCH,PROD_VERS_BUILD)
#endif
然后,您的资源文件包括
组件信息.h
,并在适当的位置使用各种定义(例如,
文件版本我的版本号
)。这种结构使我们在整个版本冲压过程中具有很大的灵活性和可追溯性。它从一个批处理文件中的一个简单块扩展到这个多层次的怪物,但在过去几年中,它对我们非常有效


我发现很难相信还没有人找到更好的方法来做到这一点。再说一次,我已经好几年没有调查过了。我假设您可以添加一个自定义的
.rules
文件,该文件定义了一个处理此问题的自定义工具。

这是一个很大的帮助,谢谢。如果这对任何人都有帮助的话,我已经为VisualStudio2008改进了它

1/在每个项目中创建/生成文件夹

2/将AssemblyInfo.cs复制到生成文件夹AssemblyInfo.cs.txt,将生成操作设置为“无”

3/编辑AssemblyInfo.cs.txt使其具有以下版本属性:

[assembly: AssemblyVersion("2.0.0.$WCREV$")]
[assembly: AssemblyFileVersion("2.0.0.$WCREV$")]
4/在预构建事件中添加了以下内容:

SubWCRev $(SolutionDir) $(ProjectDir)\Build\AssemblyInfo.cs.txt $(ProjectDir)\Properties\AssemblyInfo.cs
这在每次编译时都有效

我在VisualStudio2008中使用VisualSVN/TortoiseSVN和VisualSVN服务器

更新:


我的同事刚刚更新了他的工作副本,AssemblyInfo.cs存在冲突。看起来很明显。我已使用VisualSVN将其从SVN中排除,以解决此问题。

Program.X的答案非常有效。不过,我想补充一点,如果您在提交更改之前构建了可执行文件,那么修订版本将比运行代码的实际修订版本号少一个。要缓解此问题,可以将版本设置为

"2.0.$WCREV$.$WCMODS?1:0$"

如果有任何局部修改,则在末尾加1,否则加0。因此,如果您稍后查看您的可执行文件并查看2.0.54.1,您就知道它实际上可能是第55版。

SubWCRev也可以单独提供给那些不想(想)使用乌龟的人vn:这是我今天的事实:)…而且看起来单独提供的
SubWCRev
是静态编译的,所以你只需要exe文件,不需要一堆乌龟的DLL。嗨,这对资源文件不起作用。它以某种方式替换了手写.h文件中的$WCREV$字符串,而不是.rc文件。我创建了一个version.template文件,它是一个包含版本信息的资源文件。我将其提供给subwcrev以生成实际的.rc文件,但$WCREV$字符串仍保持原样。有人有主意吗?不管怎样,我解决了。我在.rc文件中加入了我的自定义.h文件,一切都按预期进行。关于WCREV中可用关键字的更多信息,请参见:Good point。我注意到,这看起来是一个很好的解决方法来标记它。我喜欢这个,因为你可以看到这个版本是SVN内容的1:1版本还是修改版本。