MSBuild用于更新AssemblyInfo文件。

12
我正在编写一个批处理文件来自动执行一系列任务。其中之一是通过编辑解决方案中各个项目中的assemblyinfo.cs文件来更新dll版本,最后调用msbuild.exe来编译解决方案。
在这方面,是否有可能编写一个命令行脚本来更新我的.NET解决方案中的各种assemblyinfo.cs文件。我更喜欢从命令行本身调用msbuild,而不是创建另一个msbuild脚本文件。
如何使用MSBuild实现这一点?还有其他方法吗?
感谢您的时间...

使用 msbuild: https://dev59.com/xG455IYBdhLWcg3wD_yZ#4970347 - James Woolfenden
2
下投票者是否有理由进行负面评价,还是仅仅是情绪不佳? - user20358
5个回答

11

使用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文件清空了。 - user20358
1
抱歉,管道在完成/开始读取文件之前截断了原始文件。我已经编辑了一个修复示例,将读取原始内容作为单独的步骤。 - StephenD

10

以下是我的 MSBuild 目标代码,用于更新所有的 assemblyinfo.cs 文件(在使用此目标之前,您需要初始化 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>

我正在使用来自MSBuildCommunityTasks的FileUpdate任务


或者,您可以使用“FileUpdate”任务一次,并将“Regex”参数指定为“Regex =”(\ d +)\。 (\ d +)\。 (\ d +)\。 (\ d +)“。 - Derek W
@RhysBevilaqua:你能提供一个示例吗(其中AssemblyFileVersion和AssemblyVersion应该相同)? - Derek W
你不能仅仅使用(\d+.){3}\d+匹配任何行,因为该字符串格式可能存在于其他属性、注释或其他地方。那么你的“InternalsVisibleTo”属性呢?如果你完全限定程序集,它们将具有版本号。 - Rhys Bevilaqua

7

有没有适用于修改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
@user20358 确定,只需将其放入.proj文件中,并使用类似于以下内容的命令调用MSBuild:"%windir%\Microsoft.NET\Framework\v4.0.30319\MSBuild.exe" /nologo /verbosity:normal publish.proj %* /property:ReleaseTier=stable - Cilvic

3

这是一个有着已接受答案的相当老的问题,但由于持续集成构建服务器的限制,我也希望能够通过批处理文件而非PowerShell或MS Build任务来完成此操作。以下是我的解决方案 - 假定解决方案目录为当前目录:

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 文件中删除所有空行


0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接