I am writing a batch file to automate a series of tasks. One of these tasks is to update the version of the dlls in my solution, by editing the assemblyinfo.cs file in the vario
A fairly old question with an accepted answer, but I also (due to limitations on the CI build server) wanted to do this via a batch file instead of powershell or MS Build Tasks. Here is what I came up with - assumes the solution directory is the current directory:
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.
Explanation
Basically this will recurse all the subfolders and identify AssemblyInfo.cs files, and then line-by-line copy the files to a new file. If any of the assembly version entries are found they are omitted. Then, at the end of each file, it appends the supplied version numbers.
For those batch gurus out there, some might ask why I prefer using for /F
with dir /s
instead of for /R
to iterate over the files. Basically, its because I find the recursive for to be a bit clunky since it will execute for all sub-directories (not just matching files) when no wildcards are supplied. Using the dir
command is more consistent and easier to predict.
Note: This batch file will remove all empty lines from the AssemblyInfo.cs files
This is the MSBuild target code where I update all my assemblyinfo.cs files (You have to init AssemblyInfoFilesToUpdate items collections before using this target):
<!-- 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>
I'm using FileUpdate task from MSBuildCommunityTasks.
Use the WriteCodeFragment MSBuild Task. Refer to this answer for an example.
Isn't there an MS Build task for modifying the assemblyInfo.cs
we have something like this in our 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>
Editing files with dos cmd batch files is pretty hairy without the help of other tools. You would need to use something like the for /f command to step through the lines, and then process each line. For example look for the line that starts: "[assembly: AssemblyVersion" and replace it with something else.
However, if you don't have much in your AssemblyInfo.cs (and remember you can split the AssemblyInfo.cs into multiple cs files if you want) I'd suggest creating the file from scratch with a couple of echo statements.
If you have other tools available like sed.exe the edits can be done easily.
My preference these days would be to go for a trivial powershell script, that could eat this for breakfast and gives you access to the .Net libraries if you need it.
Here's a templating form of it:
(Get-Content AssemblyInfo.template.cs) -replace "{version}","1.2.3.4" > AssemblyInfo.cs
Here's a form that uses regular expressions to replace whatever version number is there:
$x = 'Version("{0}")' -f "1.2.3.4"
$content = Get-Content AssemblyInfo.cs
$content -replace 'Version\(".*"\)',$x > AssemblyInfo.cs