2010-01-11 27 views
14

Hii, có nhiều người khác đã đăng rất nhiều câu hỏi về điều này .. Nhưng ở đây kịch bản khác.Làm thế nào để đọc assemblyversion từ assemblyInfo.cs?

Tôi cần trích xuất ba chữ số đầu tiên, ví dụ: $(major).$(Minor).$(Build) từ số phiên bản. làm thế nào tôi có thể làm điều này ?? .. Tôi đã thử AssemblyInfo Nhiệm vụ..nhưng nhiệm vụ đó chỉ dành cho việc ghi đè số phiên bản.không trích xuất số phiên bản.

Tôi cần trích xuất ba số đầu tiên và gán chúng cho một số thuộc tính.để sử dụng thêm.

tốt, tôi có thể ghi đè lên chúng bằng cách sử FileUpdate task.like ::

<FileUpdate 
    Files="@(AssemblyFile)" 
    Regex='(\d+)\.(\d+)\.(\d+)\.(\d+)' 
    ReplacementText='$1.$2.$3.$(Revision)'> 
</FileUpdate> 

nay làm thế nào tôi có thể sử dụng tức là giá trị của họ. $1,$2,$3 để gán cho thuộc tính. ???

Thanx.

Trả lời

-3

Giải pháp duy nhất là viết tác vụ tạo tùy chỉnh và phân tích cú pháp số phiên bản theo cách thủ công trong mã.

+0

Không có giải pháp nào khác. ?? mà tôi có thể thực hiện với biểu thức chính quy? hoặc nếu có bất kỳ nhiệm vụ cho nó? –

+0

Vâng tôi đã viết nhiệm vụ của riêng tôi cho nó và tôi đã sử dụng phương pháp chuỗi đơn giản để phân tích cú pháp số phiên bản nhưng tôi chắc chắn bạn có thể làm điều đó với regex quá. Nhưng bạn sẽ phải viết nhiệm vụ của riêng bạn cho điều này anyway, trừ khi bạn tìm thấy một giải pháp out-of-the-box. –

+0

http://blog.tentaclesoftware.com/archive/2009/05/03/38.aspx – Eddie

0

Bạn có thể sử dụng MSBuild.Community.Tasks.AssemblyInfo.AssemblyVersion để truy cập AssemblyVersion và AssemblyFileVersion từ AssemblyInfo.cs.

Thực tế, tác vụ này chỉ có thể được sử dụng để đặt phiên bản.

Có thể this post hữu ích.

+1

thanx filburt, nhưng tác vụ này không được sử dụng để đọc assemblyversion hoặc assemblyfileversion. Nó chỉ có thể ghi đè lên chúng bởi tài sản. –

+0

Có lẽ điều này có thể giúp: http://weblogs.asp.net/dmckinstry/archive/2007/02/06/poor-man-s-assemblyinfo-check-in-msbuild.aspx – Filburt

0

Tôi sử dụng tác vụ RegexMatch từ MSBuild.Community.Tasks.

Bạn có thể viết kết quả khớp của một nhóm mục, mặc dù bạn muốn đọc nó thành 3 thuộc tính, như trên, một nhiệm vụ tùy chỉnh sẽ được ưu tiên.

27

Bạn có thể đọc các dòng từ các tập tin, có được chuỗi sử dụng regex và thay đổi nó nếu bạn cần . Và nếu bạn đang sử dụng MSBuild 4.0, bạn có thể sử dụng các hàm thuộc tính, cho phép bạn truy cập vào .NET API. Ví dụ này sẽ cung cấp cho bạn ba số đầu tiên của AssemblyVersion.

<Target Name="ReadAssemblyVersion"> 

    <ReadLinesFromFile File="$(VersionFile)"> 
     <Output TaskParameter="Lines" 
       ItemName="ItemsFromFile"/> 
    </ReadLinesFromFile> 

    <PropertyGroup> 
     <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+)</Pattern> 
     <In>@(ItemsFromFile)</In> 
     <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out> 
    </PropertyGroup> 

    <Message Text="Output : $(Out.Remove(0, 28))"/> 

</Target> 

http://blogs.msdn.com/b/visualstudio/archive/2010/04/02/msbuild-property-functions.aspx

9

Xây dựng về câu trả lời của Alex, tôi sử dụng RegEx để đọc AssemblyVersion (và các thông tin khác) và sử dụng rằng trong WiX/MSI filename và phiên bản chuỗi của tôi. Hy vọng câu trả lời của tôi không quá ồn ào.

Đây là đầu tệp .wixproj của tôi. Điểm đáng chú ý là người đầu tiên PropertyGroup, OutputNameDefineConstants:

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    <PropertyGroup> 
     <In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\..\MyApplication\Properties\AssemblyInfoCommon.cs'))</In> 
     <Pattern>^\s*\[assembly: AssemblyVersion\(\D*(\d+)\.(\d+)\.(\d+)</Pattern> 
     <AssemblyVersionMajor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyVersionMajor> 
     <AssemblyVersionMinor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[2].Value)</AssemblyVersionMinor> 
     <AssemblyVersionBuild>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[3].Value)</AssemblyVersionBuild> 
     <Pattern>^\s*\[assembly: AssemblyDescription\(\s*"([^"]+)"</Pattern> 
     <AssemblyDescription>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyDescription> 
     <Pattern>^\s*\[assembly: AssemblyProduct\(\s*"([^"]+)"</Pattern> 
     <AssemblyProduct>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyProduct> 
     <Pattern>^\s*\[assembly: AssemblyCompany\(\s*"([^"]+)"</Pattern> 
     <AssemblyCompany>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyCompany> 
    </PropertyGroup> 
    <PropertyGroup> 
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> 
     <Platform Condition=" '$(Platform)' == '' ">x86</Platform> 
     <ProductVersion>3.7</ProductVersion> 
     <ProjectGuid>MYGUID00-840B-4055-8251-F2B83BC5DBB9</ProjectGuid> 
     <SchemaVersion>2.0</SchemaVersion> 
     <OutputName>$(AssemblyProduct)-$(AssemblyVersionMajor).$(AssemblyVersionMinor).$(AssemblyVersionBuild)</OutputName> 
     <OutputType>Package</OutputType> 
     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> 
     <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath> 
    </PropertyGroup> 
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> 
     <OutputPath>bin\$(Configuration)\</OutputPath> 
     <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath> 
     <DefineConstants>Debug;AssemblyVersionMajor=$(AssemblyVersionMajor);AssemblyVersionMinor=$(AssemblyVersionMinor);AssemblyVersionBuild=$(AssemblyVersionBuild);AssemblyDescription=$(AssemblyDescription);AssemblyProduct=$(AssemblyProduct);AssemblyCompany=$(AssemblyCompany)</DefineConstants> 
     <SuppressValidation>False</SuppressValidation> 
    </PropertyGroup> 
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> 
     <OutputPath>bin\$(Configuration)\</OutputPath> 
     <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath> 
     <DefineConstants>AssemblyVersionMajor=$(AssemblyVersionMajor);AssemblyVersionMinor=$(AssemblyVersionMinor);AssemblyVersionBuild=$(AssemblyVersionBuild);AssemblyDescription=$(AssemblyDescription);AssemblyProduct=$(AssemblyProduct);AssemblyCompany=$(AssemblyCompany)</DefineConstants> 
    </PropertyGroup> 

Và sau đó trong một.tập tin wxi Tôi có điều này:

<?define MajorVersion="$(var.AssemblyVersionMajor)" ?> 
<?define MinorVersion="$(var.AssemblyVersionMinor)" ?> 
<?define BuildVersion="$(var.AssemblyVersionBuild)" ?> 
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?> 

Và cuối cùng trong Product.wxs tôi:

<?include Definitions.wxi ?> 
<Product Id="$(var.GuidProduct)" Name="$(var.AssemblyProduct) $(var.VersionNumber)" Language="!(loc.LANG)" 
     Version="$(var.VersionNumber)" Manufacturer="$(var.AssemblyCompany)" UpgradeCode="$(var.GuidUpgrade)"> 
    <Package Id="$(var.GuidPackage)" InstallerVersion="301" Compressed="yes" InstallScope="perMachine" 
      Keywords="!(loc.Keywords)" Description="$(var.AssemblyProduct)" Comments="$(var.AssemblyDescription)" /> 
9

tạo ảnh vui nhộn luồng, xây dựng dựa trên công trình của Alex và RobPol, tôi đã có thể để xác định tính chất msbuild mở rộng đó là lấy cảm hứng từ semver.org (Major, Minor, Patch, PreRelease). Tôi đã chọn để phân tích AssemblyInformalVersion vì đó là thuộc tính duy nhất tương thích với SemVer. Dưới đây là ví dụ của tôi:

<PropertyGroup> 
    <In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs'))</In> 
    <Pattern>\[assembly: AssemblyInformationalVersion\("(?&lt;Major&gt;\d+)\.(?&lt;Minor&gt;\d+)\.(?&lt;Patch&gt;[\d]+)(?&lt;PreReleaseInfo&gt;[0-9A-Za-z-.]+)?</Pattern> 
    <AssemblyVersionMajor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["Major"].Value)</AssemblyVersionMajor> 
    <AssemblyVersionMinor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["Minor"].Value)</AssemblyVersionMinor> 
    <AssemblyVersionPatch>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["Patch"].Value)</AssemblyVersionPatch> 
    <AssemblyVersionPreRelease>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["PreReleaseInfo"].Value)</AssemblyVersionPreRelease> 
</PropertyGroup> 

Bạn có thể kiểm tra đầu ra của hoạt động này bằng cách thêm dòng sau vào csproj của bạn:

<Target Name="AfterBuild"> 
    <Message Text="$(AssemblyVersionMajor)"></Message> 
    <Message Text="$(AssemblyVersionMinor)"></Message> 
    <Message Text="$(AssemblyVersionPatch)"></Message> 
    <Message Text="$(AssemblyVersionPreRelease)"></Message> 
</Target> 

Ex: Snippet từ AssemblyInfo.cs của tôi:

[assembly: AssemblyInformationalVersion("0.9.1-beta")] 

Sẽ xuất: Chính: '0', Nhỏ: '9', Bản vá: '1', PreRelease: '-beta'

+1

Chắc chắn là câu trả lời đúng cho câu hỏi này! – fharreau

+0

câu trả lời tuyệt vời. Làm việc cho tôi. –

0

Nếu bạn muốn có thể bắt đầu ss tệp AssemblyInfo của bạn với độ chính xác 100% bạn có thể sử dụng tác vụ C# + Roslyn.

public class ReadAssemblyInfo : Task { 
    [Required] 
    public string AssemblyInfoFilePath { get; set; } 

    [Output] 
    public TaskItem AssemblyVersion { get; set; } 

    [Output] 
    public TaskItem AssemblyInformationalVersion { get; set; } 

    [Output] 
    public TaskItem AssemblyFileVersion { get; set; } 

    public override bool Execute() { 
     using (var reader = new StreamReader(AssemblyInfoFilePath)) { 
      var text = reader.ReadToEnd(); 

      var tree = CSharpSyntaxTree.ParseText(text); 
      var root = (CompilationUnitSyntax)tree.GetRoot(); 

      var attributeLists = root.DescendantNodes().OfType<AttributeListSyntax>(); 
      foreach (var p in attributeLists) { 
       foreach (var attribute in p.Attributes) { 
        var identifier = attribute.Name as IdentifierNameSyntax; 

        if (identifier != null) { 
         var value = ParseAttribute("AssemblyInformationalVersion", identifier, attribute); 
         if (value != null) { 
          SetMetadata(AssemblyInformationalVersion = new TaskItem(value.ToString()), value); 
          break; 
         } 

         value = ParseAttribute("AssemblyVersion", identifier, attribute); 
         if (value != null) { 
          SetMetadata(AssemblyVersion = new TaskItem(value.ToString()), value); 
          break; 
         } 

         value = ParseAttribute("AssemblyFileVersion", identifier, attribute); 
         if (value != null) { 
          SetMetadata(AssemblyFileVersion = new TaskItem(value.ToString()), value); 
          break; 
         } 
        } 
       } 
      } 
     } 

     return !Log.HasLoggedErrors; 
    } 

    private void SetMetadata(TaskItem taskItem, Version version) { 
     taskItem.SetMetadata(nameof(version.Major), version.Major.ToString()); 
     taskItem.SetMetadata(nameof(version.Minor), version.Minor.ToString()); 
     taskItem.SetMetadata(nameof(version.Build), version.Build.ToString()); 
     taskItem.SetMetadata(nameof(version.Revision), version.Revision.ToString()); 
    } 

    private static Version ParseAttribute(string attributeName, IdentifierNameSyntax identifier, AttributeSyntax attribute) { 
     if (identifier.Identifier.Text.IndexOf(attributeName, StringComparison.Ordinal) >= 0) { 
      AttributeArgumentSyntax listArgument = attribute.ArgumentList.Arguments[0]; 

      var rawText = listArgument.Expression.GetText().ToString(); 
      if (!string.IsNullOrWhiteSpace(rawText)) { 
       rawText = rawText.Replace("\"", ""); 
       Version version; 
       if (Version.TryParse(rawText, out version)) { 
        return version; 
       } 
      } 
     } 
     return null; 
    } 
} 
Các vấn đề liên quan