2010-02-10 68 views
7

我的任務是使用msbuild自動執行構建過程。我們有大約20個Visual C++項目和20個C#項目,這讓手工編輯所有版本字符串變得非常痛苦。我們的版本號是在編譯時生成的,因此我們需要在命令行中將完整版本字符串作爲屬性傳遞。使用MSBuild更新C++資源文件中的FILEVERSION導致編譯失敗

我最初的實現使用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遇到的第一個錯誤,但是當我diff 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 

我也開放給其他方法的任何建議,以達到同樣的目標。

+0

您必須替換'。'用FILEVERSION中的','在File |中進行設置屬性| DLL的詳細信息選項卡。 – 2011-10-20 16:35:51

回答

7

Replace TaskAction在rc文件使用ASCII編碼時插入Unicode字符。將TextEncoding =「ASCII」添加到所有rc替換任務中會生成可編譯文件。

使用ASCII字符集的限制是您不能使用©符號。 但是,如果您選擇解決問題的TextEncoding =「Windows-1252」。

+1

我試圖做與[MSBuild社區任務]的(http://msbuildtasks.tigris.org/)'FileUpdate'任務相同。他們公開了一個工作相同的'Encoding'屬性。 – 2011-10-20 16:48:26

+2

<! - MSBuild.Community.Tasks.dll版本 - > \t granadaCoder 2012-10-15 18:40:41

+0

Upvote for Jared。並且對安東尼M大喊......自從我使用MSBuild.Community.Tasks ...並且你的(AnthonyM's)評論是什麼使我的谷歌搜索...找到一場比賽。我的問題是,沒有設置編碼...我得到了一些奇怪的人物出現在我的結果。奇怪的字符是:? – granadaCoder 2012-10-15 18:42:59

4

我會從AssemblyInfo.cs*.rc文件中分離出版本信息。創建一個AssemblyVersion.csVersion.rc文件,其中包含所有程序集的(通用)版本信息。您可以在構建開始時生成這些文件。由於它們只包含版本信息,因此不必使用正則表達式,因此每次都可以覆蓋整個文件。

+0

「任何事情都可以通過一層間接尋址解決」 – 2010-02-12 18:48:43

+0

一個體面的建議。手工編輯所有這些文件一次肯定比每次構建都要好,但是我們仍在向構建中添加新項目,並且這些新增功能無縫銜接會很好。另外,我內在的程序員懶惰讓我抱着一種解決方案的希望,讓我避免任何手工編輯。 – Jared 2010-02-12 19:22:13

+0

即使您繼續使用自動化解決方案,這仍是有效的建議。任何時候你可以避免一個正則表達式,你是金:) – 2011-10-20 16:56:01

3

您仍然需要用逗號(,)替換FILEVERSION中的句點(.)。如果構建的格式不正確,則不會在文件的屬性|中看到文件版本詳情頁面。我會繼續爲PRODUCTVERSION做同樣的事情,儘管這似乎沒有必要。

我用MSBuild Property Functions。我相信你可以正則表達/替換它們。

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

你能告訴我你如何處理財產。我遇到同樣的問題,但無法解決它。 @Anthony Mastrean – Ani 2017-01-27 23:25:38