Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read AssemblyFileVersion from AssemblyInfo post-compile

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>

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

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

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?

like image 502
Gregyski Avatar asked Aug 09 '09 19:08

Gregyski


People also ask

What are the contents of AssemblyInfo CS file?

AssemblyInfo. cs contains information about your assembly, like name, description, version, etc. You can find more details about its content reading the comments that are included in it.

What is assembly versioning explain with example?

Assembly version number For example, version 1.5. 1254.0 indicates 1 as the major version, 5 as the minor version, 1254 as the build number, and 0 as the revision number.

What is the difference between assembly version and assembly file version?

Answers. 1) AssemblyVersion is a . NET specific thing and is used by the CLR when trying to find assemblies by version #. 2) FileVersion and ProductVersion are native version numbers used by Windows proper.


2 Answers

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.

like image 199
Gregyski Avatar answered Sep 20 '22 13:09

Gregyski


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

like image 45
kzu Avatar answered Sep 19 '22 13:09

kzu