Ответ 1
Единственное решение - написать задачу пользовательской сборки и проанализировать номер версии вручную в коде.
Hii, есть много других, которые уже поставили столько вопросов об этом. Но здесь сценарий отличается.
Мне нужно извлечь первые три цифры, т.е. $(major).$(Minor).$(Build)
из номер версии.
как я могу это сделать?.. Я попробовал AssemblyInfo
Task..but эта задача только для перезаписывания номера версии. Не для извлечения номера версии.
Мне нужно извлечь первые три числа и назначить их некоторому свойству. для дальнейшего использования.
ну, я могу перезаписать их, используя FileUpdate
task.like::
<FileUpdate
Files="@(AssemblyFile)"
Regex='(\d+)\.(\d+)\.(\d+)\.(\d+)'
ReplacementText='$1.$2.$3.$(Revision)'>
</FileUpdate>
Теперь, как я могу использовать их значение, т.е. $1,$2,$3
для назначения свойствам.???
Thanx.
Единственное решение - написать задачу пользовательской сборки и проанализировать номер версии вручную в коде.
Вы можете читать строки из файлов, получать строку с использованием регулярного выражения и изменять ее, если вам нужно. И если вы используете 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
Основываясь на ответе Алекса, я использовал 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)" />
Удивительная нить, основанная на работе Alex и RobPol, я смог определить расширенные свойства msbuild, вдохновленные semver.org(Major, Minor, Patch, PreRelease). Я решил проанализировать AssemblyInformalVersion, поскольку это единственный атрибут, совместимый с SemVer. Вот мой пример:
<PropertyGroup>
<In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\Properties\AssemblyInfo.cs'))</In>
<Pattern>\[assembly: AssemblyInformationalVersion\("(?<Major>\d+)\.(?<Minor>\d+)\.(?<Patch>[\d]+)(?<PreReleaseInfo>[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'
Я только что нашел это в 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;
Вы можете использовать MSBuild.Community.Tasks.AssemblyInfo.AssemblyVersion для доступа к AssemblyVersion и AssemblyFileVersion из AssemblyInfo.cs.забастовкa >
В действительности эту задачу можно использовать только для установки версии.
Может быть этот пост полезен.
Я использую задачу RegexMatch из MSBuild.Community.Tasks.
Вы можете записать вывод соответствия в группу элементов, хотя вы хотите прочитать его в 3 свойствах, как указано выше, тогда будет предпочтительной пользовательская задача.
Если вы хотите обрабатывать файл AssemblyInfo со 100% -ной точностью, вы можете использовать задачу С# + 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;
}
}