【问题标题】:MSbuild for updating the assemblyinfo file用于更新 assemblyinfo 文件的 MSbuild
【发布时间】:2012-01-05 08:17:32
【问题描述】:

我正在编写一个批处理文件来自动执行一系列任务。其中一项任务是通过在我的解决方案的各个项目中编辑 assemblyinfo.cs 文件来更新我的解决方案中的 dll 版本;最后调用msbuild.exe编译解决方案。

在这方面,是否可以编写一个命令行脚本来更新我的 .net 解决方案中的各种 assemblyinfo.cs 文件。我宁愿从命令行本身调用 msbuild,而不是创建另一个 msbuild 脚本文件。

如何使用 MSBuild 做到这一点?还有其他方法吗?

感谢您的宝贵时间...

【问题讨论】:

标签: .net msbuild automation build-automation


【解决方案1】:

如果没有其他工具的帮助,使用 dos cmd 批处理文件编辑文件非常麻烦。 您需要使用 for /f 命令之类的东西来逐行遍历,然后处理每一行。例如查找开头的行:“[assembly: AssemblyVersion” 并用其他东西替换它。

但是,如果您的 AssemblyInfo.cs 中没有太多内容(请记住,如果需要,您可以将 AssemblyInfo.cs 拆分为多个 cs 文件),我建议您使用几个 echo 语句从头开始创建文件.

如果您有其他可用的工具,例如 sed.exe,则可以轻松完成编辑。

这些天我的偏好是使用一个简单的 powershell 脚本,它可以把它当早餐吃,如果你需要的话,它可以让你访问 .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

【讨论】:

  • 我不懂正则表达式。我尝试了您上面建议的行,它清除了 AssemblyInfo.cs 文件。
  • 很抱歉,管道在完成/开始读取之前截断了原始文件。我已经编辑了示例并修复了将原始内容作为单独步骤读取的问题。
【解决方案2】:

这是我更新所有 assemblyinfo.cs 文件的 MSBuild 目标代码(在使用此目标之前,您必须初始化 AssemblyInfoFilesToUpdate 项目集合):

  <!-- 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 task from MSBuildCommunityTasks

【讨论】:

  • 您也可以通过将Regex 参数指定为Regex="(\d+)\.(\d+)\.(\d+)\.(\d+)" 来使用FileUpdate 任务一次。
  • @RhysBevilaqua:您能否提供一个示例(其中 AssemblyFileVersion 和 AssemblyVersion 必须相同)?
  • 你不能只用 (\d+\.){3}\d+ 匹配任何行,因为这种格式的字符串可能存在于其他属性或 cmets 或其他任何东西中。你的“InternalsVisibleTo”属性呢?如果您是完全合格的程序集,它们将具有版本号。
【解决方案3】:

是否有修改 assemblyInfo.cs 的 MS Build 任务

我们的 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>

【讨论】:

  • 我可以把它放在我的批处理文件中吗?我正在寻找可以从我的批处理文件中调用的东西...... msbuild {这里有一堆参数......}
  • @user20358 确保将其放入 .proj 文件并使用以下内容调用 MSBuild:"%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" /nologo /verbosity :normal publish.proj %* /property:ReleaseTier=stable
【解决方案4】:

一个相当老的问题,答案已被接受,但我也(由于 CI 构建服务器的限制)想通过批处理文件而不是 powershell 或 MS 构建任务来做到这一点。这是我想出的 - 假设解决方案目录是当前目录:

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 /Fdir /s 而不是for /R 来迭代文件。基本上,这是因为我发现递归 for 有点笨拙,因为当没有提供通配符时,它将针对所有子目录(不仅仅是匹配文件)执行。使用dir 命令更一致,更容易预测。

注意:此批处理文件将从 AssemblyInfo.cs 文件中删除所有空行

【讨论】:

    【解决方案5】:

    使用WriteCodeFragment MSBuild Task。示例请参考this answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-12
      • 1970-01-01
      • 2012-05-29
      • 2010-10-07
      • 2011-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多