【问题标题】:Read AssemblyFileVersion from AssemblyInfo post-compile从 AssemblyInfo 后编译读取 AssemblyFileVersion
【发布时间】:2010-11-18 03:06:58
【问题描述】:

如何读取 AssemblyFileVersion 或其组件 AssemblyFileMajorVersionAssemblyFileMinorVersionAssemblyFileBuildNumber .csproj 中的 AssemblyFileRevision,在编译之后?

我尝试了以下从构建的程序集中提取信息的方法:

<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 而不是从中检索值。

我怎样才能最好地做到这一点?

【问题讨论】:

  • +1 仅用于询问“我如何阅读它”而不是您总是找到的:如何更新版本信息。
  • 自从我问这个问题已经两个月了,唯一可用的答案是我自己的,我将继续接受它。我仍然认为可能有更好的方法。
  • @Yoopergeek:确实,有几种写作方法,但即使经过大量研究,阅读也难以捉摸。但是,我在下面的回答确实很好。

标签: .net msbuild assemblies versioning


【解决方案1】:

我已经设法使用自定义任务解决了这个问题。类库 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 更新:

必须进行一项额外的更改才能在每个版本上更新ApplicationVersionInitialTargets="AfterCompile" 必须添加到 &lt;Project...。这是solved by Chao Kuo

【讨论】:

【解决方案2】:

如果使任务继承自 AppDomainIsolatedTask,则无需从流中加载程序集。您可以只使用 AppDomain.LoadFrom(file)。

【讨论】:

    【解决方案3】:

    复制 assmelby 然后在副本上运行组装任务怎么样?

    赛义德·易卜拉欣·哈希米

    【讨论】:

    • 我想找一些更优雅的东西,但我会试一试。但是,我必须检查这是否适用于后续构建,或者文件锁定错误是否会阻碍未来的副本。如果是这样,我每次都需要复制到不同的文件名,这变得更加不雅。我会让你知道情况如何。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-19
    • 1970-01-01
    相关资源
    最近更新 更多