2009-08-09 68 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)。