How to read the assemblyversion from assemblyInfo.cs?

Viewed 12564

Hii, there are many others had already post so many question about this..But here the scenario is different.

I need to extract the first three digits ie. $(major).$(Minor).$(Build) from version number. how can i do this??..i tried AssemblyInfo Task..but that task is just for overwriting the version number.not to extract the version number.

I need to extract first three number and assign them to some property.for further use.

well,i can overwrite them using FileUpdate task.like ::

<FileUpdate 
    Files="@(AssemblyFile)" 
    Regex='(\d+)\.(\d+)\.(\d+)\.(\d+)' 
    ReplacementText='$1.$2.$3.$(Revision)'>
</FileUpdate>

now how can i use their value ie. $1,$2,$3 to assign to properties.???

Thanx.

8 Answers

If you want to be able to process your AssemblyInfo file with 100% accuracy you can use a C# task + Roslyn.

public class ReadAssemblyInfo : Task {
    [Required]
    public string AssemblyInfoFilePath { get; set; }

    [Output]
    public TaskItem AssemblyVersion { get; set; }

    [Output]
    public TaskItem AssemblyInformationalVersion { get; set; }

    [Output]
    public TaskItem AssemblyFileVersion { get; set; }

    public override bool Execute() {
        using (var reader = new StreamReader(AssemblyInfoFilePath)) {
            var text = reader.ReadToEnd();

            var tree = CSharpSyntaxTree.ParseText(text);
            var root = (CompilationUnitSyntax)tree.GetRoot();

            var attributeLists = root.DescendantNodes().OfType<AttributeListSyntax>();
            foreach (var p in attributeLists) {
                foreach (var attribute in p.Attributes) {
                    var identifier = attribute.Name as IdentifierNameSyntax;
                    
                    if (identifier != null) {
                        var value = ParseAttribute("AssemblyInformationalVersion", identifier, attribute);
                        if (value != null) {
                            SetMetadata(AssemblyInformationalVersion = new TaskItem(value.ToString()), value);
                            break;
                        }

                        value = ParseAttribute("AssemblyVersion", identifier, attribute);
                        if (value != null) {
                            SetMetadata(AssemblyVersion = new TaskItem(value.ToString()), value);
                            break;
                        }

                        value = ParseAttribute("AssemblyFileVersion", identifier, attribute);
                        if (value != null) {
                            SetMetadata(AssemblyFileVersion = new TaskItem(value.ToString()), value);
                            break;
                        }
                    }
                }
            }
        }

        return !Log.HasLoggedErrors;
    }

    private void SetMetadata(TaskItem taskItem, Version version) {
        taskItem.SetMetadata(nameof(version.Major), version.Major.ToString());
        taskItem.SetMetadata(nameof(version.Minor), version.Minor.ToString());
        taskItem.SetMetadata(nameof(version.Build), version.Build.ToString());
        taskItem.SetMetadata(nameof(version.Revision), version.Revision.ToString());
    }

    private static Version ParseAttribute(string attributeName, IdentifierNameSyntax identifier, AttributeSyntax attribute) {
        if (identifier.Identifier.Text.IndexOf(attributeName, StringComparison.Ordinal) >= 0) {
            AttributeArgumentSyntax listArgument = attribute.ArgumentList.Arguments[0];

            var rawText = listArgument.Expression.GetText().ToString();
            if (!string.IsNullOrWhiteSpace(rawText)) {
                rawText = rawText.Replace("\"", "");
                Version version;
                if (Version.TryParse(rawText, out version)) {
                    return version;
                }
            }
        }
        return null;
    }
}

I use the RegexMatch-task from the MSBuild.Community.Tasks.

You can write the output of the match to an itemgroup, although you want to read it into 3 properties, as above, a custom task would then be prefered.

The only solution is to write a custom build task, and parse the version number manually in the code.

Related