2012-01-05 63 views
11

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

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

如何使用MSBuild做到这一点?有没有其他方法可以做到这一点?

感谢您的时间...

+0

使用msbuild:http://stackoverflow.com/questions/4562845/how-can-i-change-assembly-version-number-using-assemblyinfotask/4970347#4970347 – 2012-01-05 14:03:33

+2

贬低选民是否有理由倒下投票还是投票者只是度过了糟糕的一天? – user20358 2012-03-30 12:36:42

回答

9

与DOS CMD批处理文件编辑的文件是没有其他工具的帮助相当毛。 您需要使用类似于for/f命令的内容来遍历这些行,然后处理每一行。例如,查找开始的行:“[assembly:AssemblyVersion” 并将其替换为其他内容。

但是,如果您的AssemblyInfo.cs中没有太多内容(并且记住可以将AssemblyInfo.cs拆分为多个cs文件(如果需要的话)),我建议您从零开始创建文件,声明。

如果您有像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 
+0

我不知道正则表达式。我试过了你上面建议的那一行,它清除了AssemblyInfo.cs文件。 – user20358 2012-01-05 12:34:53

+1

对不起,管道在完成/开始读取之前会截断原始文件。我已经修改了该示例并将其作为单独的步骤读取原始内容。 – StephenD 2012-01-06 20:52:51

7

是不是有一个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> 
+0

我可以把它放在我的批处理文件中吗?我正在寻找一些我可以从我的批处理文件中调出的东西,比如...... msbuild {下面的一大堆参数..} – user20358 2012-01-05 18:03:45

+0

@ user20358确定把它放到一个.proj文件中,并用类似下面的方法调用MSBuild:“ %windir%\ Microsoft.NET \ Framework \ v4.0.30319 \ MSBuild.exe“/ nologo/verbosity:normal publish.proj%*/property:ReleaseTier = stable – Cilvic 2012-01-06 09:48:20

8

这是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> 

我使用FileUpdate task from MSBuildCommunityTasks

+0

或者,您可以使用'FileUpdate'任务一次指定' (\ d +)\。(\ d +)\。(\ d +)“'的正则表达式参数。 – 2014-08-04 16:39:51

+0

@DerekW这可能会产生意想不到的后果。 – 2015-01-13 04:49:31

+0

@RhysBevilaqua:你能否提供一个例子(其中AssemblyFileVersion和AssemblyVersion是相同的)? – 2015-01-13 05:03:13

2

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

SetVersion。蝙蝠

@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迭代文件。基本上,因为我发现递归有点笨重,因为当没有通配符提供时,它将执行所有子目录(不仅仅是匹配文件)。使用dir命令更加一致并且更易于预测。

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

+0

哇。非常感谢你。这节省了我很多工作 – 2018-02-16 14:41:13