Read AssemblyFileVersion from AssemblyInfo post-compile

江枫思渺然 提交于 2019-11-27 22:17:01
Gregyski

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

And in the project file:

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

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

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:

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.

If you make the task inherit from AppDomainIsolatedTask, you don't need to the assembly loading from streams. You can just use AppDomain.LoadFrom(file).

What about copying the assmelby and then running the Assembly task on the copy?

Sayed Ibrahim Hashimi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!