Dot-Net

從 AssemblyInfo 後編譯讀取 AssemblyFileVersion

  • December 1, 2012

編譯後如何在 .csproj 中讀取AssemblyFileVersion或其組件AssemblyFileMajorVersionAssemblyFileMinorVersionAssemblyFileBuildNumberAssemblyFileRevision ?

我嘗試了以下從建構的程序集中提取資訊的方法:

<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.... 這被趙闊解決了

引用自:https://stackoverflow.com/questions/1252002