2009-08-09 26 views
12

Làm thế nào người ta có thể đọc AssemblyFileVersion, hoặc các thành phần của nó AssemblyFileMajorVersion, AssemblyFileMinorVersion, AssemblyFileBuildNumber, AssemblyFileRevision, trong csproj, sau biên dịch?đọc AssemblyFileVersion từ AssemblyInfo sau biên dịch

Tôi đã thử những điều sau đây mà kéo thông tin từ lắp ráp xây dựng:

<Target Name="AfterCompile"> 
    <GetAssemblyIdentity AssemblyFiles="$(TargetPath)"> 
     <Output 
      TaskParameter="Assemblies" 
      ItemName="MyAssemblyIdentities"/> 
    </GetAssemblyIdentity> 
    <Message Text="AssemblyVersion = %(MyAssemblyIdentities.Version)" /> 
</Target> 

Nhưng đó lấy AssemblyVersion và không phải là AssemblyFileVersion. Có vẻ như không phải là mục nhập siêu dữ liệu được ghi lại cho mục sau. Tôi cũng đã thử:

<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> 

Thật không may, trong khi điều này lấy giá trị chính xác, nó cũng khóa lắp ráp cho đến khi VS2008 bị đóng.

Thẳng thắn, không phải là những gì tôi muốn vì tôi thà đọc thông tin từ AssemblyInfo.cs trực tiếp. Tuy nhiên, tôi không thể tìm ra cách để làm điều đó. Tôi giả định AssemblyInfo trong MSBuild mở rộng là một cách, nhưng có vẻ như tập trung vào văn bản cho AssemblyInfo và không lấy các giá trị từ nó.

Làm cách nào để tôi có thể thực hiện điều này tốt nhất?

+2

+1 chỉ đơn giản là hỏi "Làm cách nào để đọc" thay vì những gì bạn luôn tìm thấy: Cách cập nhật thông tin phiên bản. – Yoopergeek

+0

Vì đã hai tháng kể từ khi tôi hỏi câu hỏi này và câu trả lời có thể sử dụng duy nhất là của riêng tôi, tôi sẽ tiếp tục và chấp nhận nó. Tôi vẫn nghĩ rằng có thể có một cách tốt hơn. – Gregyski

+0

@Yoopergeek: Thật vậy, có một số phương pháp để viết, nhưng đọc được khó nắm bắt ngay cả sau khi rất nhiều nghiên cứu. Câu trả lời của tôi dưới đây, tuy nhiên, làm việc tốt. – Gregyski

Trả lời

11

Tôi đã giải quyết được vấn đề này bằng cách sử dụng tác vụ tùy chỉnh. Thư viện lớp DLL là như vậy (một số mã điều chỉnh/loại bỏ cho ngắn gọn):

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; } 
    } 
} 

Và trong hồ sơ dự án:

<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> 

Tôi đã thử nghiệm này và nó sẽ đọc các phiên bản cập nhật nếu bạn sử dụng MSBuild.ExtensionPack.VersionNumber.targets để tự động phiên bản. Rõ ràng, điều này có thể dễ dàng mở rộng để một regex được chuyển từ tập tin dự án sang một nhiệm vụ tùy chỉnh có mục đích tổng quát hơn để thu được bất kỳ kết quả nào trong bất kỳ tệp nào.


Cập nhật 2009/09/03:

Một thay đổi bổ sung phải được thực hiện để làm cho ApplicationVersion cập nhật trên từng xây dựng. InitialTargets="AfterCompile" phải được thêm vào <Project.... Đây là solved by Chao Kuo.

+0

Lưu ý rằng regex được sử dụng ở trên là sửa đổi câu trả lời của Jonathan Leffler cho bài viết SO "Kết hợp các phần số phiên bản với cụm từ thông dụng" @ http://stackoverflow.com/questions/400522/matching-version-number-parts-with biểu thức bất thường – Gregyski

0

Điều gì về sao chép assmelby và sau đó chạy nhiệm vụ Assembly trên bản sao?

Đã nói Ibrahim Hashimi

+0

Tôi muốn tìm thứ gì đó tao nhã hơn một chút, nhưng tôi sẽ thử. Tôi sẽ phải kiểm tra, tuy nhiên, nếu điều đó sẽ làm việc cho các bản xây dựng tiếp theo hoặc nếu lỗi khóa tập tin sẽ cản trở các bản sao trong tương lai. Nếu có, tôi cần phải sao chép vào một tên tệp khác nhau mỗi lần, điều này càng trở nên không phù hợp. Tôi sẽ cho bạn biết làm thế nào nó đi. Cảm ơn. – Gregyski

1

Nếu bạn thực hiện tác vụ kế thừa từ AppDomainIsolatedTask, bạn không cần tải bản lắp ráp từ luồng. Bạn chỉ có thể sử dụng AppDomain.LoadFrom (tệp).

Các vấn đề liên quan