在这方面,是否有可能编写一个命令行脚本来更新我的.NET解决方案中的各种assemblyinfo.cs文件。我更喜欢从命令行本身调用msbuild,而不是创建另一个msbuild脚本文件。
如何使用MSBuild实现这一点?还有其他方法吗?
感谢您的时间...
使用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
以下是我的 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\(".*"\)\]"
ReplacementText="AssemblyVersion("$(BuildVersion)")]" />
<!-- Update AssemblyFileVersion -->
<FileUpdate Files="@(AssemblyInfoFilesToUpdate)"
Regex="AssemblyFileVersion\(".*"\)\]"
ReplacementText="AssemblyFileVersion("$(BuildVersion)")]" />
<Message Text="AssemblyInfo files updated to version "$(BuildVersion)"" />
</Target>
我正在使用来自MSBuildCommunityTasks的FileUpdate任务。
有没有适用于修改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>
这是一个有着已接受答案的相当老的问题,但由于持续集成构建服务器的限制,我也希望能够通过批处理文件而非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 /F
和 dir /s
,而不是 for /R
来迭代文件。基本上,这是因为当没有通配符时,我发现递归的 for 对于所有子目录(而不仅仅是匹配的文件)的执行有点笨拙。使用 dir
命令更加一致和易于预测。
注意:此批处理文件将从 AssemblyInfo.cs 文件中删除所有空行