2010-09-13 3 views
4

У меня есть файл MSBuild, который обрабатывает файл AssemblyInfo перед компиляцией приложения. В конце сборки он восстанавливает файл AssemblyInfo. Он делает это, создавая резервную копию файла, манипулируя им, а затем после времени сборки восстанавливая файл.Как всегда выполнять цель в MSBuild

Это работает довольно хорошо, за исключением случаев, когда во время сборки возникает ошибка. Затем он не восстанавливает исходный файл. Есть ли способ сообщить MSBuild о выполнении цели в конце сборки независимо от того, удалось ли это или не удалось?

+0

В MSBuild нет такой функции, встроенной в MSBuild. Можете ли вы лучше объяснить, что вы делаете, чтобы другие могли предоставить некоторые альтернативы? –

+0

Конечно ... В основном я пытаюсь это сделать: 1.) Скопируйте сборкуinfo.cs в файл резервной копии (assemblyinfo.cs.original) 2.) Измените assemblyinfo.cs, чтобы включить информацию об управлении версиями. Информация о версиях исходит из пользовательской задачи MSBuild. 3.) Составьте приложение и/или сборку 4.) Замените файл assemblyInfo.cs исходным файлом (assemblyinfo.cs.original) Я хочу, чтобы на этапе 4 произошла ошибка, возникающая во время процесса сборки. –

ответ

2

Что об изменении проблемы:

  • Добавить в «шаблон» AssemblyInfo.cs.template для контроля версий, которая представляет свой «идеальный» AssemblyInfo.cs с регулярными выражениями крюков там
  • Перед сборкой, копия шаблон для реального и применить ваши регулярные выражения
  • Добавить какой-то недосмотр subversion для AssemblyInfo.cs (я не эксперт по svn, но я уверен, что вы можете сказать ему игнорировать определенные файлы)
  • В случае, если вашим разработчикам необходимо добавить какой-либо пользовательский интерфейс зации, которые обычно появляются в AssemblyInfo.cs (например InternalsVisibleTo), а затем получить их, чтобы добавить его в разные .cs файл, который проверяется.

В качестве дополнительного уточнения, смешайте решение Сайед с моим и удалите информацию о версии версии из фактического AssemblyInfo.cs и установите флажок VersionInfo.cs.template, который создает VersionInfo.cs в BeforeBuild.

+0

Интересная идея ... Мне нужно подумать об этом, но я думаю, что это может быть ближе к решению, которое будет работать. Если он преуспевает, он компилируется в «файл шаблона». Если это не удается, файл шаблона остается там, но файл, который я хочу защитить, не изменяется. –

+0

Мне было бы интересно услышать, что вы делаете в конце. Удачи! –

0

Я никогда не использовал его, но из документации кажется, что OnError Element полезен для того, чего вы пытаетесь достичь.

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

+0

Я уже использую элемент OnError для своих пользовательских целей/задач. Это работает сказочно. Проблема в том, что ошибка возникает за пределами объекта, который находится под моим контролем. Поэтому я бы хотел, чтобы супер-catch все, что работает как OnError для любой задачи. –

+0

@ Джейсон, в этом случае мне жаль, что я не могу оказать дальнейшую помощь. –

5

Основываясь на вашем последнем комментарии к исходному вопросу, я хотел бы воспользоваться другим подходом и забыть подход, который вы сейчас используете. Вы должны знать, что ваша информация о версии не обязательно должна быть в файле AssemblyInfo.cs. Он может быть в любом файле кода, если у вас есть только атрибуты AssemblyVersion и AssemblyFileVersion, определенные после каждого. Что было сказано, что я хотел бы сделать это выполните следующие действия:

  1. Удалить AssemblyVersion & AssemblyFileVersion из AssemblyInfo.cs
  2. Создать новый файл, назовите его, что вы хотите хотите в моем случае я положил его в свойствах \ VersionInfo.cs. Не добавляйте этот файл в проект.
  3. Редактировать файл проекта, чтобы включить этот файл в списке файлов для компиляции только тогда, когда вы хотите

Разложим немного на # 3. Когда вы создаете .NET-проект, сам проект является файлом MSBuild. Внутри этого файла вы найдете элемент, объявленный компиляцией. Это список файлов, которые будут отправлены компилятору для компиляции. Вы можете динамически включать/исключать файлы из этого списка. В этом случае вы хотите включить файл VersionInfo.cs только в том случае, если вы строите сервер сборки (или какое-либо другое условие, которое вы определяете). В этом примере я определил, какое условие должно быть, если проект строился в режиме Release. Таким образом, для режима Release VersionInfo.cs будет отправлен в компилятор, а для других сборок - нет. Вот содержание VersionInfo.cs

VersionInfo.cs

[assembly: System.Reflection.AssemblyVersion("1.2.3.4")] 
[assembly: System.Reflection.AssemblyFileVersion("1.2.3.4")] 

Для того, чтобы зацепить это в процессе сборки, вы должны отредактировать файл проекта. В этом файле вы найдете элемент (возможно, более 1 в зависимости от типа проекта). Вы должны добавить цель, подобную следующей.

<Target Name="BeforeCompile"> 
    <ItemGroup Condition=" '$(Configuration)'=='Release' "> 
    <Compile Include="Properties\VersionInfo.cs" /> 
    </ItemGroup> 
</Target> 

Вот что я сделал здесь, чтобы определить цель, BeforeCompile, которая хорошо известна цель, вы можете переопределить. См. Это MSDN article о других аналогичных целях. В основном это цель, которая всегда будет вызываться до вызова компилятора. В этой цели я добавляю VersionInfo.cs к элементу Compile только в том случае, если для свойства Configuration установлено значение release. Вы можете определить это свойство как угодно.Например, если у вас есть TFS в качестве сервера сборки, то это может быть,

<Target Name="BeforeCompile"> 
    <ItemGroup Condition=" '$(TeamFoundationServerUrl)'!='' "> 
    <Compile Include="Properties\VersionInfo.cs" /> 
    </ItemGroup> 
</Target> 

Потому что мы знаем, что TeamFoundationServerUrl определяется только при создании с помощью TFS.

Если вы строите образуют командную строку, то что-то вроде этого

<Target Name="BeforeCompile"> 
    <ItemGroup Condition=" '$(IncludeVersionInfo)'=='true' "> 
    <Compile Include="Properties\VersionInfo.cs" /> 
    </ItemGroup> 
</Target> 

И когда вы строите проект просто MSBuild.exe YourProject.proj/р: IncludeVersion = TRUE. Примечание: при построении решения это не сработает.

+0

Интересно, но я не уверен, как это решает проблему. Позвольте мне рассказать о том, что я делаю. Когда я хочу отправить выпуск для тестирования, я создаю ветвь в subversion, которая указывает номер версии. Затем моя пользовательская задача MSBuild считывает в какой ветке находится рабочая копия (а также другая информация, такая как номер версии и т. Д.). Затем он модифицирует assemblyinfo.cs для встраивания такой информации. При сбое восстанавливает исходную версию файла. Причиной этого является то, что мое регулярное выражение «знает», где нужно модифицировать информацию. –

+0

Что еще более важно, я не создаю бесконечный цикл незафиксированных изменений таким образом. Если я выполняю версию 1.0.0.0, у меня нет измененного файла из-за просто создания проекта. Вместо этого файл изменяется только тогда, когда мне это нужно (во время сборки). Я не хочу, чтобы мои разработчики помнили об этом вручную. Идея состоит в том, что я могу посмотреть на любой файл и точно узнать, откуда он и как он был построен. Поэтому, если кто-то выпускает хлам на prod-сервере, я знаю, кто виноват и какая именно версия кода мне нужно изменить. –

+0

+1 Мне нравится решение. слишком плохой cruisecontrol не автоматически определяет свойство, подобное этому. – Maslow

Смежные вопросы