Dot-Net
從 AssemblyInfo 後編譯讀取 AssemblyFileVersion
編譯後如何在 .csproj 中讀取AssemblyFileVersion或其組件AssemblyFileMajorVersion、AssemblyFileMinorVersion、AssemblyFileBuildNumber、AssemblyFileRevision ?
我嘗試了以下從建構的程序集中提取資訊的方法:
<Target Name="AfterCompile"> <GetAssemblyIdentity AssemblyFiles="$(TargetPath)"> <Output TaskParameter="Assemblies" ItemName="MyAssemblyIdentities"/> </GetAssemblyIdentity> <Message Text="AssemblyVersion = %(MyAssemblyIdentities.Version)" /> </Target>但這會檢索AssemblyVersion而不是AssemblyFileVersion。後者似乎沒有記錄在案的元數據條目。我也試過:
<Import Project="$(MSBuildExtensionsPath)\ExtensionPack\MSBuild.ExtensionPack.tasks" /> <Target Name="AfterCompile"> <MSBuild.ExtensionPack.Framework.Assembly TaskAction="GetInfo" NetAssembly="$(TargetPath)"> <Output TaskParameter="OutputItems" ItemName="Info" /> </MSBuild.ExtensionPack.Framework.Assembly> <Message Text="AssemblyFileVersion = %(Info.FileVersion)" /> </Target>不幸的是,雖然這會檢索到正確的值,但它也會文件鎖定程序集,直到 VS2008 關閉。
坦率地說,這也不是我想要的,因為我寧願直接從 AssemblyInfo.cs 中讀取資訊。但是,我無法弄清楚如何做到這一點。我認為 MSBuild Extensions 中的 AssemblyInfo 是一種方式,但它似乎專注於寫入 AssemblyInfo 而不是從中檢索值。
我怎樣才能最好地做到這一點?
我已經設法使用自定義任務解決了這個問題。類庫 DLL 就是這樣(為簡潔起見調整/刪除了一些程式碼):
using System; using System.IO; using System.Text.RegularExpressions; using Microsoft.Build.Framework; namespace GetAssemblyFileVersion { public class GetAssemblyFileVersion : ITask { [Required] public string strFilePathAssemblyInfo { get; set; } [Output] public string strAssemblyFileVersion { get; set; } public bool Execute() { StreamReader streamreaderAssemblyInfo = null; Match matchVersion; Group groupVersion; string strLine; strAssemblyFileVersion = String.Empty; try { streamreaderAssemblyInfo = new StreamReader(strFilePathAssemblyInfo); while ((strLine = streamreaderAssemblyInfo.ReadLine()) != null) { matchVersion = Regex.Match(strLine, @"(?:AssemblyFileVersion\("")(?<ver>(\d*)\.(\d*)(\.(\d*)(\.(\d*))?)?)(?:""\))", RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace | RegexOptions.Singleline | RegexOptions.ExplicitCapture); if (matchVersion.Success) { groupVersion = matchVersion.Groups["ver"]; if ((groupVersion.Success) && (!String.IsNullOrEmpty(groupVersion.Value))) { strAssemblyFileVersion = groupVersion.Value; break; } } } } catch (Exception e) { BuildMessageEventArgs args = new BuildMessageEventArgs(e.Message, string.Empty, "GetAssemblyFileVersion", MessageImportance.High); BuildEngine.LogMessageEvent(args); } finally { if (streamreaderAssemblyInfo != null) streamreaderAssemblyInfo.Close(); } return (true); } public IBuildEngine BuildEngine { get; set; } public ITaskHost HostObject { get; set; } } }在項目文件中:
<UsingTask AssemblyFile="GetAssemblyFileVersion.dll" TaskName="GetAssemblyFileVersion.GetAssemblyFileVersion" /> <Target Name="AfterCompile"> <GetAssemblyFileVersion strFilePathAssemblyInfo="$(SolutionDir)\AssemblyInfo.cs"> <Output TaskParameter="strAssemblyFileVersion" PropertyName="strAssemblyFileVersion" /> </GetAssemblyFileVersion> <Message Text="AssemblyFileVersion = $(strAssemblyFileVersion)" /> </Target>我已經對此進行了測試,如果您使用MSBuild.ExtensionPack.VersionNumber.targets進行自動版本控制,它將讀取更新的版本。
顯然,這可以很容易地擴展,以便將正則表達式從項目文件傳遞到更通用的自定義任務,以便在任何文件中獲得任何匹配。
2009/09/03 更新: 必須進行一項額外的更改才能
ApplicationVersion對每個建構進行更新。InitialTargets="AfterCompile"必須添加到<Project.... 這被趙闊解決了。