使用MSBuild更新C ++资源文件中的FILEVERSION会导致编译失败

时间:2010-02-10 17:33:30

标签: visual-c++ resources msbuild

我的任务是使用msbuild自动化我们的构建过程。我们有大约20个Visual C ++项目和20个C#项目,这使得编辑所有版本字符串变得很麻烦。我们的版本号在构建时是生成的,因此我们需要在命令行上将完整版本字符串作为属性传递。

我的初始实施使用MSBuild Extension PackFile任务对.rcAssemblyInfo.cs文件进行替换。

<FileSystem.File TaskAction="Replace" Files="@(AssemblyInfoFiles)" RegexPattern='\[assembly: AssemblyVersion\(".*"\)\]' Replacement='[assembly: AssemblyVersion("$(Version)")]'/>
<FileSystem.File TaskAction="Replace" Files="@(AssemblyInfoFiles)" RegexPattern='\[assembly: AssemblyFileVersion\(".*"\)\]' Replacement='[assembly: AssemblyFileVersion("$(Version)")]'/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern="FILEVERSION\s+\S+" Replacement="FILEVERSION $(Version)"/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern="PRODUCTVERSION\s+\S+" Replacement="PRODUCTVERSION $(Version)"/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern='VALUE\s+"FileVersion",\s*".*"' Replacement='VALUE "FileVersion", "$(Version)"'/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern='VALUE\s+"ProductVersion",\s*".*"' Replacement='VALUE "ProductVersion", "$(Version)"'/>

这对AssemblyInfo.cs文件很有用,但是当我编译任何C ++项目时,我会收到这样的错误:

.\MyProject.rc(23): error RC2135: file not found: 0x09
.\MyProject.rc(71): error RC2135: file not found: 1
.\MyProject.rc(72): error RC2135: file not found: 6
.\MyProject.rc(73): error RC2135: file not found: 6
.\MyProject.rc(74): error RC2135: file not found: 0x3fL
.\MyProject.rc(80): error RC2135: file not found: FILEOS
.\MyProject.rc(81): error RC2135: file not found: 0x2L
.\MyProject.rc(84): error RC2164: unexpected value in RCDATA
.\MyProject.rc(86): error RC2135: file not found: BLOCK
.\MyProject.rc(88): error RC2135: file not found: VALUE

第23行遇到第一个错误,但是当我对源控件进行差异MyProject.rc时,一切看起来都还可以。仅更改版本号,这些更改从第72行开始,字符串0x09不会出现在文件中的任何位置。世界上到底发生了什么?第21 - 25行看起来像这样:

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32

我也对任何其他方法的建议持开放态度。

3 个答案:

答案 0 :(得分:6)

替换TaskAction正在插入Unicode字符,而rc文件使用ASCII编码。将TextEncoding =“ASCII”添加到所有rc替换任务会导致可编译文件。

使用ASCII字符集的限制是您不能使用©符号。 但如果您选择TextEncoding =“Windows-1252”来解决问题。

答案 1 :(得分:4)

我会从AssemblyInfo.cs*.rc文件中分离出版本信息。创建一个AssemblyVersion.csVersion.rc文件,其中包含所有程序集的(通用)版本控制信息。您将在构建开始时生成这些内容。因为它们只包含版本信息,所以您不必使用正则表达式,每次都可以覆盖整个文件。

答案 2 :(得分:3)

您仍需要用逗号(.)替换FILEVERSION中的句点(,)。如果在没有正确格式的情况下构建,则不会在文件的属性中看到文件版本详情页面。我会继续为PRODUCTVERSION做同样的事情,尽管似乎没有必要。

我使用了MSBuild Property Functions。我相信你也可以正则/替换它们。

<FileSystem.File TaskAction="Replace" 
                 TextEncoding="ASCII" 
                 Files="@(AppResource)" 
                 RegexPattern="FILEVERSION\s+\S+" 
                 Replacement="FILEVERSION $(Version.Replace('.',','))"/>