We use a CommonAssemblyInfo.cs file, to contain all common AssemblyInfo information for all projects.
Like:
[assembly: AssemblyVersion("0.0.0.0")] [assembly: AssemblyFileVersion("0.0.0.0")] [assembly: AssemblyCompanyAttribute("ADA ICT")] [assembly: AssemblyCopyrightAttribute("Copyright © ADA ICT 2014")]
Our continuous integration system, alters the CommonAssemblyInfo.cs file add build time, to sync the TFS build version with the assemblies found in the solution.
When you add this CommonAssemblyInfo.cs file as a link to your project in Microsoft Visual Studio:
Microsoft Visual Studio, will merge the information in the AssemblyInfo.cs with the information in the CommonAssemblyInfo.cs.
If you don’t want to add this link manual, you can use the following C# code:
VsSolution.cs
namespace Research.Core.CodeGeneration { using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; public class VsSolution { /// <summary> /// Add CommonAssemblyInfo as link to a project. /// </summary> public string AddCommonAssemblyInfo(string content) { string result = string.Empty; if (!string.IsNullOrWhiteSpace(content)) { result = content; var findRegEx = new Regex(@"<ItemGroup>.* <Compile Include=""..\\SharedSource\\CommonAssemblyInfo.cs""> <Link>CommonAssemblyInfo.cs</Link> </Compile>.* </ItemGroup>", RegexOptions.Singleline); if (!findRegEx.IsMatch(content)) { var replaceRegEx = new Regex(@"<ItemGroup>"); result = replaceRegEx.Replace(result, @"<ItemGroup> <Compile Include=""..\\SharedSource\\CommonAssemblyInfo.cs""> <Link>CommonAssemblyInfo.cs</Link> </Compile>", 1); } } return result; } } }
This code can be used with a small helper class to change all *.csproj files on disk:
FileSystem.cs
namespace Research.Core.Components { using System; using System.Collections.Generic; using System.IO; using System.Threading.Tasks; public class FileSystem { public async Task FindAndReplace(string path, string searchPattern, SearchOption searchOption, Func<string, string> updateContent) { string[] files = await GetFilesAsync(path, searchPattern, searchOption); foreach (string file in files) { string content = await ReadAllTextAsync(file); content = updateContent(content); await WriteAllTextAsync(file, content); } } public async Task<string[]> GetFilesAsync(string path, string searchPattern, SearchOption searchOption) { return await Task.Factory.StartNew(() => { return Directory.GetFiles(path, searchPattern, searchOption); }); } public async Task<string> ReadAllTextAsync(string path) { string result = await Task.Factory.StartNew(() => { return File.ReadAllText(path); }); return result; } public async Task WriteAllTextAsync(string path, string content) { await Task.Factory.StartNew(() => { File.WriteAllText(path, content); }); } } }
To execute the code use:
[TestMethod] public void FindAndReplace_should_replace_common_assemblyinfo() { var solution = new VsSolution(); var fs = new FileSystem(); Task task = fs.FindAndReplace(@"C:\Projects\TNT\RouteMaker\Main-v1.0\Source",
"AssemblyInfo.cs", System.IO.SearchOption.AllDirectories, solution.RemoveCommonAssemblyInfo); task.Wait(); }
Code can be found at:
https://github.com/roelvanlisdonk/Research