2009-08-09 66 views
12

如何才能讀取的AssemblyFileVersion,或其組件AssemblyFileMajorVersionAssemblyFileMinorVersionAssemblyFileBuildNumberAssemblyFileRevision,在.csproj的範圍內,以下編譯?讀的AssemblyFileVersion從集信息後編譯

我已經試過這拉從內置組件的信息如下:

<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並且不從中檢索值。

我該如何最好的完成這件事?

+2

+1只是詢問「我如何閱讀」而不是總是找到的內容:如何更新版本信息。 – Yoopergeek 2009-10-06 18:42:41

+0

既然我問了這個問題已經兩個月了,唯一可用的答案是我自己的,我會繼續接受它。我仍然認爲可能有更好的辦法。 – Gregyski 2009-10-08 19:11:03

+0

@Yoopergeek:的確,有幾種寫作方法,但即使經過大量研究,閱讀也難以實現。然而,我的回答確實很好。 – Gregyski 2009-10-08 19:11:49

回答

11

我管理這個使用自定義任務來解決。類庫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...。這是solved by Chao Kuo

+0

請注意,上面使用的正則表達式是Jonathan Leffler對SO文章「匹配具有正則表達式的版本號部分」的修改答案@ http://stackoverflow.com/questions/400522/matching-version-number-parts-with -常用表達 – Gregyski 2009-08-10 07:03:51

0

如何複製assmelby,然後在副本上運行Assembly任務?

賽義德·易卜拉欣·哈希米

+0

我想找點更優雅的東西,但我會試一試。但是,我必須檢查這是否適用於後續版本,或者如果文件鎖定錯誤會阻止未來的副本。如果是這樣,我需要每次都複製到不同的文件名,這會變得更加不雅。我會讓你知道它是怎麼回事。謝謝。 – Gregyski 2009-08-09 23:16:56

1

如果您將任務從AppDomainIsolatedTask繼承,則不需要從流中加載程序集。你可以使用AppDomain.LoadFrom(file)。