У меня есть требование установить несколько проектов веб-установки (с использованием VS2005 и ASP.Net/C#) в одну виртуальную папку. Проекты имеют общие ссылки на сборки (все файловые системы структурированы для использования одной и той же папки bin), что делает развертывание изменений в этих сборках проблематичным, поскольку установщик MS перезапишет сборки только в том случае, если текущая установленная версия старше, чем версия в MSI.
Я не утверждаю, что пессимистическая схема установки неверна - только то, что она создает проблемы в среде, с которой мне было поручено работать. Поскольку существует значительное количество общих сборок и значительное количество разработчиков, которые могут изменить общую сборку, но забывают обновить ее номер версии, попытка управления версиями вручную в конечном итоге приведет к огромной путанице во время установки.
С другой стороны, важно не обновлять номера версий спонтанно и не заменять общие сборки все установкой каждый, поскольку это может (по крайней мере временно) скрыть случаи, когда были внесены фактические изменения.
Тем не менее, то, что я ищу, - это средство для обновления информации о версии сборки (желательно с использованием MSBuild) только в тех случаях, когда компоненты сборки (модули кода, ресурсы и т. д.) Действительно изменились.
Я нашел несколько ссылок, которые хотя бы частично относятся к здесь (задача AssemblyInfo в MSDN) и здесь (похоже на то, что мне нужно, но старше двух лет и без четкого решения).
Моя команда также использует контроль версий TFS, поэтому автоматизированное решение, вероятно, должно включать средства, с помощью которых AssebmlyInfo можно будет извлекать / загружать во время сборки.
Любая помощь приветствуется.
Заранее спасибо.





Я не могу ответить на все ваши вопросы, так как у меня нет опыта работы с TFS.
Но я могу порекомендовать лучший подход для обновления ваших файлов AssemblyInfo.cs, чем использование задачи AssemblyInfo. Эта задача, по-видимому, просто воссоздает стандартный файл AssemblyInfo с нуля и теряет любые настраиваемые части, которые вы могли добавить.
По этой причине я предлагаю вам изучить задачу FileUpdate из проекта MSBuild Community Tasks. Он может искать конкретное содержимое в файле и заменять его, например:
<FileUpdate
Files = "$(WebDir)\Properties\AssemblyInfo.cs"
Regex = "(\d+)\.(\d+)\.(\d+)\.(\d+)"
ReplacementText = "$(Major).$(ServicePack).$(Build).$(Revision)"
Condition = "'$(Configuration)' == 'Release'"
/>
Есть несколько способов контролировать приращение номера сборки. Поскольку я хочу, чтобы номер сборки увеличивался только в том случае, если сборка была полностью успешной, я использую двухэтапный метод:
Существуют такие задачи, как ReadLinesFromFile, которые могут вам в этом помочь, но мне показалось, что проще всего написать небольшую настраиваемую задачу:
using System;
using System.IO;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
namespace CredibleCustomBuildTasks
{
public class IncrementTask : Task
{
[Required]
public bool SaveChange { get; set; }
[Required]
public string IncrementFileName { get; set; }
[Output]
public int Increment { get; set; }
public override bool Execute()
{
if (File.Exists(IncrementFileName))
{
string lines = File.ReadAllText(IncrementFileName);
int result;
if (Int32.TryParse(lines, out result))
{
Increment = result + 1;
}
else
{
Log.LogError("Unable to parse integer in '{0}' (contents of {1})");
return false;
}
}
else
{
Increment = 1;
}
if (SaveChange)
{
File.Delete(IncrementFileName);
File.WriteAllText(IncrementFileName, Increment.ToString());
}
return true;
}
}
}
Я использую это перед FileUpdateTask, чтобы получить следующий номер сборки:
<IncrementTask
IncrementFileName = "$(BuildNumberFile)"
SaveChange = "false">
<Output TaskParameter = "Increment" PropertyName = "Build" />
</IncrementTask>
и в качестве последнего шага (перед тем, как уведомить других) в сборке:
<IncrementTask
IncrementFileName = "$(BuildNumberFile)"
SaveChange = "true"
Condition = "'$(Configuration)' == 'Release'" />
Другой вопрос о том, как обновить номер версии только при изменении исходного кода, сильно зависит от того, как процесс сборки взаимодействует с системой управления версиями. Обычно проверка изменений исходного файла должна инициировать сборку с непрерывной интеграцией. Это тот, который нужно использовать для обновления соответствующего номера версии.
Я написал одну индивидуальную задачу, вы можете сослаться на приведенный ниже код. Он создаст утилиту, в которую вы можете передать информацию о сборке, путь Major, minor и номер сборки. вы можете изменить его, чтобы получить номер редакции. Поскольку в моем случае эту задачу выполнил разработчик, я искал ее и снова заменял целую строку.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Text.RegularExpressions;
namespace UpdateVersion
{
class SetVersion
{
static void Main(string[] args)
{
String FilePath = args[0];
String MajVersion=args[1];
String MinVersion = args[2];
String BuildNumber = args[3];
string RevisionNumber = null;
StreamReader Reader = File.OpenText(FilePath);
string contents = Reader.ReadToEnd();
Reader.Close();
MatchCollection match = Regex.Matches(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", RegexOptions.IgnoreCase);
if (match[0].Value != null)
{
string strRevisionNumber = match[0].Value;
RevisionNumber = strRevisionNumber.Substring(strRevisionNumber.LastIndexOf(".") + 1, (strRevisionNumber.LastIndexOf("\"")-1) - strRevisionNumber.LastIndexOf("."));
String replaceWithText = String.Format("[assembly: AssemblyVersion(\"{0}.{1}.{2}.{3}\")]", MajVersion, MinVersion, BuildNumber, RevisionNumber);
string newText = Regex.Replace(contents, @"\[assembly: AssemblyVersion\("".*""\)\]", replaceWithText);
StreamWriter writer = new StreamWriter(FilePath, false);
writer.Write(newText);
writer.Close();
}
else
{
Console.WriteLine("No matching values found");
}
}
}
}
Ненавижу это говорить, но похоже, что вы делаете это неправильно. Гораздо проще, если вы создаете версии сборки на лету, а не пытаетесь их исправлять.
Взгляните на https://sbarnea.com/articles/easy-windows-build-versioning/
Почему я думаю, что вы делаете это неправильно? * Сборка не должна изменять номер версии * если вы создадите один и тот же набор изменений дважды, вы должны получить одинаковые номера сборки * если вы поместите номер сборки внутри того, что Microsoft называет номером сборки (правильное имя будет на уровне PATCH), вы в конечном итоге достигнете ограничения 65535.