Использование MSBuild для обновления FILEVERSION в файле ресурсов C++ приводит к сбоям компиляции
мне было поручено автоматизировать процесс сборки с помощью msbuild. У нас есть около двадцати проектов Visual C++ и двадцать проектов C#, что делает боль вручную редактировать все строки версии. Наши номера версий генерируются во время сборки, поэтому нам нужно передать строку полной версии как свойство в командной строке.
моя первоначальная реализация используется Расширение В MSBuild Пакет ' s File
задача сделать замены на .rc
и AssemblyInfo.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="FILEVERSIONs+S+" Replacement="FILEVERSION $(Version)"/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern="PRODUCTVERSIONs+S+" Replacement="PRODUCTVERSION $(Version)"/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern='VALUEs+"FileVersion",s*".*"' Replacement='VALUE "FileVersion", "$(Version)"'/>
<FileSystem.File TaskAction="Replace" Files="@(RCFiles)" RegexPattern='VALUEs+"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
Я также открыт для любых предложений по другим методам достижения той же цели.
3 ответов
функция Replace taskaction вставляла символы Юникода, в то время как rc-файлы используют кодировку ASCII. Добавление TextEncoding= "ASCII" ко всем задачам замены rc приводит к компилируемым файлам.
ограничение использования набора символов ASCII заключается в том, что вы не можете использовать символ©. Но если вы выберете TextEncoding= "Windows-1252", это решит проблему.
Я бы отделил информацию о версии от AssemblyInfo.cs
и *.rc
файлы. Создайте AssemblyVersion.cs
и Version.rc
файл, который содержит (общую) информацию о версиях для всех ваших сборок. Вы создадите их в начале сборки. Поскольку они содержат только сведения о версиях, которые не нужно использовать регулярные выражения, можно перезаписать весь файл каждый раз.
вам все еще нужно заменить периоды (.
) в FILEVERSION
с запятыми (,
). Если вы создаете без правильного формата, вы не увидите версию файла на странице свойств | сведений о файле. Я бы пошел вперед и сделал то же самое для PRODUCTVERSION
, хотя в этом нет необходимости.
я использовал MSBuild Функции Собственность. Я уверен, что вы можете regex/заменить их тоже.
<FileSystem.File TaskAction="Replace"
TextEncoding="ASCII"
Files="@(AppResource)"
RegexPattern="FILEVERSION\s+\S+"
Replacement="FILEVERSION $(Version.Replace('.',','))"/>