MSbuild для обновления файла assemblyinfo

Я пишу пакетный файл для автоматизации ряда задач. Одна из этих задач - обновить версию DLL в моем решении, отредактировав файл assemblyinfo.cs в различных проектах моего решения; а затем, наконец, вызывая msbuild.exe для компиляции решения.

В этом отношении можно ли написать командную строку script для обновления различных файлов assemblyinfo.cs в моем .net-решении. Я бы предпочел вызывать msbuild из самой командной строки и не создавать другой скриптовый файл msbuild.

Как это сделать с помощью MSBuild? Есть ли другой способ сделать это?

Спасибо за ваше время...

Ответ 1

Редактирование файлов с пакетными файлами dos cmd довольно волосатое без помощи других инструментов. Вам нужно будет использовать что-то вроде команды for/f для перехода по строкам, а затем обрабатывать каждую строку. Например, найдите строку, которая начинается: "[сборка: AssemblyVersion" и замените его чем-то другим.

Однако, если у вас не так много в AssemblyInfo.cs(и помните, что вы можете разделить AssemblyInfo.cs на несколько файлов cs, если хотите), я бы предложил создать файл с нуля с помощью нескольких выражений эха.

Если у вас есть другие инструменты, такие как sed.exe, редактирование может быть выполнено легко.

Мое предпочтение в наши дни состояло бы в том, чтобы пойти на тривиальную powershell script, которая может съесть это на завтрак и даст вам доступ к библиотекам .Net, если вам это нужно.

Здесь шаблонная форма:

(Get-Content AssemblyInfo.template.cs) -replace "{version}","1.2.3.4" > AssemblyInfo.cs

Здесь форма, использующая регулярные выражения для замены любого номера версии:

$x = 'Version("{0}")' -f "1.2.3.4"
$content = Get-Content AssemblyInfo.cs
$content -replace 'Version\(".*"\)',$x > AssemblyInfo.cs

Ответ 2

Это целевой код MSBuild, в котором я обновляю все мои файлы assemblyinfo.cs(перед использованием этой цели вы должны инициализировать сборку сборных файлов):

  <!-- Update all the assembly info files with generated version info -->
  <Target Name="AfterGet" Condition="'$(ServerBuild)'=='true' And '$(BuildVersion)'!=''">
    <Message Text="Modifying AssemblyInfo files..." />
    <!-- Clear read-only attributes -->
    <Attrib Files="@(AssemblyInfoFilesToUpdate)" Normal="true" />
    <!-- Update AssemblyVersion -->
    <FileUpdate Files="@(AssemblyInfoFilesToUpdate)"
            Regex="AssemblyVersion\(&quot;.*&quot;\)\]"
            ReplacementText="AssemblyVersion(&quot;$(BuildVersion)&quot;)]" />
    <!-- Update AssemblyFileVersion -->
    <FileUpdate Files="@(AssemblyInfoFilesToUpdate)"
            Regex="AssemblyFileVersion\(&quot;.*&quot;\)\]"
            ReplacementText="AssemblyFileVersion(&quot;$(BuildVersion)&quot;)]" />
    <Message Text="AssemblyInfo files updated to version &quot;$(BuildVersion)&quot;" />
  </Target>

Я использую задачу FileUpdate из MSBuildCommunityTasks.

Ответ 3

Не существует ли задачи сборки MS для изменения assemblyInfo.cs

у нас есть что-то подобное в нашем publish.proj

<Target Name="SolutionInfo">
    <Message Text="Creating Version File:     $(Major).$(Minor).$(Build).$(Revision)"/>


<AssemblyInfo
        CodeLanguage="CS"
        OutputFile="$(BuildInputDir)\SolutionInfo.cs"
        AssemblyTitle="$(Company) $(Product)$(ProductAppendix)"
        AssemblyDescription="$(Company) $(Product)$(ProductAppendix)"
        AssemblyCompany="$(Company)"
        AssemblyProduct="$(Product)"
        AssemblyCopyright="Copyright © $(Company)"    
        ComVisible="false"
        CLSCompliant="false"
        Guid="9E77382C-5FE3-4313-B099-7A9F24A4C328"
        AssemblyVersion="$(Major).$(Minor).$(Build).$(Revision)"
        AssemblyFileVersion="$(Major).$(Minor).$(Build).$(Revision)" />
</Target>

Ответ 4

Довольно старый вопрос с принятым ответом, но я также (из-за ограничений на сервере сборки CI) хотел сделать это через командный файл вместо powershell или MS Build Tasks. Вот что я придумал - предполагает, что каталог решений - это текущий каталог:

SetVersion.bat

@echo off
setlocal enabledelayedexpansion

if [%1] == [] GOTO :USAGE
set version=%1
set fileversion=%1
set informationalversion=%1

if [%2] NEQ [] SET fileversion=%2
if [%3] NEQ [] SET informationalversion=%3

echo Setting assembly version information

for /F "delims=" %%f in ('dir /s /b Assemblyinfo.cs') do (
    echo ^> %%f

    pushd %%~dpf

    for /F "usebackq delims=" %%g in ("AssemblyInfo.cs") do (
        set ln=%%g
        set skip=0

        if "!ln:AssemblyVersion=!" NEQ "!ln!" set skip=1
        if "!ln:AssemblyFileVersion=!" NEQ "!ln!" set skip=1
        if "!ln:AssemblyInformationalVersion=!" NEQ "!ln!" set skip=1

        if !skip!==0 echo !ln! >> AssemblyInfo.cs.versioned
    )

    echo [assembly: AssemblyVersion^("%version%"^)] >> AssemblyInfo.cs.versioned
    echo [assembly: AssemblyFileVersion^("%fileversion%"^)] >> AssemblyInfo.cs.versioned
    echo [assembly: AssemblyInformationalVersion^("%informationalversion%"^)] >> AssemblyInfo.cs.versioned

    copy /y AssemblyInfo.cs AssemblyInfo.cs.orig
    move /y AssemblyInfo.cs.versioned AssemblyInfo.cs

    popd
)
echo Done^^!

GOTO:EOF

:USAGE
echo Usage:
echo.
echo SetVersion.bat Version [FileVersion] [InformationalVersion]
echo.

Объяснение

В основном это будет возвращать все подпапки и идентифицировать файлы AssemblyInfo.cs, а затем по очереди копировать файлы в новый файл. Если какая-либо из записей версии сборки найдена, они опущены. Затем, в конце каждого файла, он добавляет поставляемые номера версий.

Для тех партитур-гуру, некоторые могут спросить, почему я предпочитаю использовать for /F с dir /s вместо for /R для итерации по файлам. В основном, это потому, что я считаю, что рекурсивный, чтобы быть немного неуклюжим, поскольку он будет выполняться для всех подкаталогов (а не только для сопоставления файлов), когда не заданы подстановочные знаки. Использование команды dir более согласовано и легче прогнозировать.

Примечание. Этот командный файл удалит все пустые строки из файлов AssemblyInfo.cs.