Как прочитать версию сборки из assemblyInfo.cs? - PullRequest
15 голосов
/ 11 января 2010

Hii, Есть много других, которые уже опубликовали так много вопросов об этом .. Но здесь сценарий другой.

Мне нужно извлечь первые три цифры, т.е. $(major).$(Minor).$(Build) от номера версии. Как я могу это сделать ?? .. Я пытался AssemblyInfo Задача..но эта задача только для перезаписи номера версии. Не извлекать номер версии.

Мне нужно извлечь первые три числа и присвоить их некоторому свойству. Для дальнейшего использования.

хорошо, я могу перезаписать их, используя FileUpdate task.like ::

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

Теперь, как я могу использовать их значение, т.е. $1,$2,$3 для присвоения свойств. ???

Thanx.

Ответы [ 8 ]

30 голосов
/ 27 февраля 2012

Вы можете читать строки из файлов, получать строки с помощью регулярных выражений и изменять их, если вам нужно. А если вы используете MSBuild 4.0, вы можете использовать свойства функций, которые дают вам доступ к .NET API. Этот пример должен дать вам первые три числа AssemblyVersion.

<Target Name="ReadAssemblyVersion">

    <ReadLinesFromFile File="$(VersionFile)">
        <Output TaskParameter="Lines"
                ItemName="ItemsFromFile"/>
    </ReadLinesFromFile>

    <PropertyGroup>
        <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+)</Pattern>
        <In>@(ItemsFromFile)</In>
        <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
    </PropertyGroup>

    <Message Text="Output : $(Out.Remove(0, 28))"/>

</Target>

http://blogs.msdn.com/b/visualstudio/archive/2010/04/02/msbuild-property-functions.aspx

15 голосов
/ 06 февраля 2015

Потрясающий поток, опираясь на работу Алекса и RobPol, я смог определить расширенные свойства msbuild, вдохновленные semver.org (Major, Minor, Patch, PreRelease) Я решил проанализировать AssemblyInformalVersion, поскольку это единственный атрибут, совместимый с SemVer. Вот мой пример:

<PropertyGroup>
    <In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs'))</In>
    <Pattern>\[assembly: AssemblyInformationalVersion\("(?&lt;Major&gt;\d+)\.(?&lt;Minor&gt;\d+)\.(?&lt;Patch&gt;[\d]+)(?&lt;PreReleaseInfo&gt;[0-9A-Za-z-.]+)?</Pattern>
    <AssemblyVersionMajor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["Major"].Value)</AssemblyVersionMajor>
    <AssemblyVersionMinor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["Minor"].Value)</AssemblyVersionMinor>
    <AssemblyVersionPatch>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["Patch"].Value)</AssemblyVersionPatch>
    <AssemblyVersionPreRelease>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups["PreReleaseInfo"].Value)</AssemblyVersionPreRelease>
</PropertyGroup>

Вы можете проверить вывод этой операции, добавив в ваш .csproj следующее:

  <Target Name="AfterBuild">
    <Message Text="$(AssemblyVersionMajor)"></Message>
    <Message Text="$(AssemblyVersionMinor)"></Message>
    <Message Text="$(AssemblyVersionPatch)"></Message>
    <Message Text="$(AssemblyVersionPreRelease)"></Message>
</Target>

Пример: фрагмент из моего AssemblyInfo.cs:

[assembly: AssemblyInformationalVersion("0.9.1-beta")]

Будет выводить: Major: '0', Minor: '9', Patch: '1', PreRelease: '-beta'

10 голосов
/ 08 июня 2013

Опираясь на ответ Алекса, я использовал RegEx, чтобы прочитать AssemblyVersion (и другую информацию) и использовать его в своих именах файлов и версиях WiX / MSI. Надеюсь, мой ответ не слишком шумный.

Вот вершина моего файла .wixproj. Интересными являются первые PropertyGroup , OutputName и DefineConstants :

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    <PropertyGroup>
        <In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\..\MyApplication\Properties\AssemblyInfoCommon.cs'))</In>
        <Pattern>^\s*\[assembly: AssemblyVersion\(\D*(\d+)\.(\d+)\.(\d+)</Pattern>
        <AssemblyVersionMajor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyVersionMajor>
        <AssemblyVersionMinor>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[2].Value)</AssemblyVersionMinor>
        <AssemblyVersionBuild>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[3].Value)</AssemblyVersionBuild>
        <Pattern>^\s*\[assembly: AssemblyDescription\(\s*"([^"]+)"</Pattern>
        <AssemblyDescription>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyDescription>
        <Pattern>^\s*\[assembly: AssemblyProduct\(\s*"([^"]+)"</Pattern>
        <AssemblyProduct>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyProduct>
        <Pattern>^\s*\[assembly: AssemblyCompany\(\s*"([^"]+)"</Pattern>
        <AssemblyCompany>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern), System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</AssemblyCompany>
    </PropertyGroup>
    <PropertyGroup>
        <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
        <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
        <ProductVersion>3.7</ProductVersion>
        <ProjectGuid>MYGUID00-840B-4055-8251-F2B83BC5DBB9</ProjectGuid>
        <SchemaVersion>2.0</SchemaVersion>
        <OutputName>$(AssemblyProduct)-$(AssemblyVersionMajor).$(AssemblyVersionMinor).$(AssemblyVersionBuild)</OutputName>
        <OutputType>Package</OutputType>
        <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
        <WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
        <OutputPath>bin\$(Configuration)\</OutputPath>
        <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
        <DefineConstants>Debug;AssemblyVersionMajor=$(AssemblyVersionMajor);AssemblyVersionMinor=$(AssemblyVersionMinor);AssemblyVersionBuild=$(AssemblyVersionBuild);AssemblyDescription=$(AssemblyDescription);AssemblyProduct=$(AssemblyProduct);AssemblyCompany=$(AssemblyCompany)</DefineConstants>
        <SuppressValidation>False</SuppressValidation>
    </PropertyGroup>
    <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
        <OutputPath>bin\$(Configuration)\</OutputPath>
        <IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
        <DefineConstants>AssemblyVersionMajor=$(AssemblyVersionMajor);AssemblyVersionMinor=$(AssemblyVersionMinor);AssemblyVersionBuild=$(AssemblyVersionBuild);AssemblyDescription=$(AssemblyDescription);AssemblyProduct=$(AssemblyProduct);AssemblyCompany=$(AssemblyCompany)</DefineConstants>
    </PropertyGroup>

А затем в файле .wxi у меня есть это:

<?define MajorVersion="$(var.AssemblyVersionMajor)" ?>
<?define MinorVersion="$(var.AssemblyVersionMinor)" ?>
<?define BuildVersion="$(var.AssemblyVersionBuild)" ?>
<?define VersionNumber="$(var.MajorVersion).$(var.MinorVersion).$(var.BuildVersion)" ?>

И, наконец, в моем Product.wxs:

<?include Definitions.wxi ?>
<Product Id="$(var.GuidProduct)" Name="$(var.AssemblyProduct) $(var.VersionNumber)" Language="!(loc.LANG)"
         Version="$(var.VersionNumber)" Manufacturer="$(var.AssemblyCompany)" UpgradeCode="$(var.GuidUpgrade)">
    <Package Id="$(var.GuidPackage)" InstallerVersion="301" Compressed="yes" InstallScope="perMachine"
             Keywords="!(loc.Keywords)" Description="$(var.AssemblyProduct)" Comments="$(var.AssemblyDescription)" />
1 голос
/ 06 ноября 2017

Если вы хотите обрабатывать файл AssemblyInfo со 100% точностью, вы можете использовать задачу C # + 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;
    }
}
1 голос
/ 18 января 2011

Я только что нашел это в Google, может помочь:

http://msdn.microsoft.com/en-us/library/system.reflection.assemblyname.version%28v=VS.90%29.aspx

В частности:

//For AssemblyFileVersion
Assembly asm = Assembly.GetExecutingAssembly();
FileVersionInfo fvi = FileVersionInfo.GetVersionInfo(asm.Location);
string version = fvi.FileVersion
//For AssemblyVersion
string revision = Assembly.GetExecutingAssembly().GetName().Version.Revision;
0 голосов
/ 14 января 2010

Я использую RegexMatch-задачу из MSBuild.Community.Tasks.

Вы можете записать вывод совпадения в группу элементов, хотя вы хотите прочитать его в 3 свойствах, как указано выше, тогда предпочтительной будет пользовательская задача.

0 голосов
/ 11 января 2010

Вы можете использовать MSBuild.Community.Tasks.AssemblyInfo.AssemblyVersion для доступа к AssemblyVersion и AssemblyFileVersion из AssemblyInfo.cs.

Действительно, это задание можно использовать только для установки версии.

Может быть этот пост полезен.

0 голосов
/ 11 января 2010

Единственное решение - написать пользовательскую задачу сборки и вручную проанализировать номер версии в коде.

...