用户登录
用户注册

分享至

从 AssemblyInfo 后编译读取 AssemblyFileVersion

  • 作者: 猥琐寓言
  • 来源: 51数据库
  • 2023-02-13

问题描述

如何读取 AssemblyFileVersion 或其组件 AssemblyFileMajorVersionAssemblyFileMinorVersionAssemblyFileBuildNumberAssemblyFileRevision,在 .csproj 中,编译后?

How can one read the AssemblyFileVersion, or its components AssemblyFileMajorVersion, AssemblyFileMinorVersion, AssemblyFileBuildNumber, AssemblyFileRevision, within the .csproj, following compilation?

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

I have tried the following which pulls the information from the built assembly:

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

但这会检索 AssemblyVersion 而不是 AssemblyFileVersion.后者似乎没有记录在案的元数据条目.我也试过了:

But that retrieves the AssemblyVersion and not the AssemblyFileVersion. There does not seem to be a documented metadata entry for the latter. I also tried:

<Import Project="$(MSBuildExtensionsPath)ExtensionPackMSBuild.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 关闭.

Unfortunately, while this retrieves the correct value, it also file locks the assembly until VS2008 is closed.

坦率地说,这也不是我想要的,因为我宁愿直接从 AssemblyInfo.cs 中读取信息.但是,我无法弄清楚如何做到这一点.我认为 MSBuild Extensions 中的 AssemblyInfo 是一种方式,但它似乎专注于写入 AssemblyInfo 而不是从中检索值.

Frankly, neither is what I want as I would rather read the information from the AssemblyInfo.cs directly. However, I cannot figure out how to do that. I assumed AssemblyInfo in the MSBuild Extensions was one way, but it seems focused on writing to the AssemblyInfo and not retrieving values from it.

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

How can I best accomplish this?

推荐答案

我已经设法使用自定义任务解决了这个问题.类库 DLL 就是这样(为简洁起见调整/删除了一些代码):

I've managed to solve this using a custom task. The class library DLL is as so (some code adjusted/eliminated for brevity):

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 进行自动版本控制,它将读取更新的版本.

I've tested this and it will read the updated version if you use MSBuild.ExtensionPack.VersionNumber.targets for auto-versioning.

显然,这可以很容易地扩展,以便将正则表达式从项目文件传递到更通用的自定义任务,以获得任何文件中的任何匹配.


2009/09/03 更新:

Obviously, this could be easily extended so that a regex is passed from the project file to a more general-purpose custom task in order to obtain any match in any file.


Update 2009/09/03:

必须进行一项额外的更改才能在每次构建时更新 ApplicationVersion.InitialTargets="AfterCompile" 必须添加到 <Project....这是郭超解决的.

One additional change has to be made to make the ApplicationVersion update on each build. InitialTargets="AfterCompile" must be added to the <Project.... This was solved by Chao Kuo.

软件
前端设计
程序设计
Java相关