Как я могу предотвратить кэширование внешних файлов MSBuild (Visual Studio) во время сборки проекта? - PullRequest
13 голосов
/ 25 мая 2010

У меня есть проект в моем решении, который начал свою жизнь как проект библиотеки C #. Он не имеет никакого интереса с точки зрения кода, он просто используется в качестве зависимости в других проектах в моем решении, чтобы обеспечить его сборку в первую очередь. Одним из побочных эффектов создания этого проекта является то, что создается общий файл AssemblyInfo.cs, который содержит номер версии, используемый другими проектами.

Я сделал это, добавив в файл .csproj следующее:

<ItemGroup>
  <None Include="Properties\AssemblyInfo.Shared.cs.in" />
  <Compile Include="Properties\AssemblyInfo.Shared.cs" />
  <None Include="VersionInfo.targets" />
</ItemGroup>
<Import Project="$(ProjectDir)VersionInfo.targets" />
<Target Name="BeforeBuild" DependsOnTargets="UpdateSharedAssemblyInfo" />

Ссылочный файл VersionInfo.targets содержит следующее:

<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <!--
      Some properties defining tool locations and the name of the
      AssemblyInfo.Shared.cs.in file etc.
    -->
  </PropertyGroup>
  <Target Name="UpdateSharedAssemblyInfo">
    <!--
      Uses the Exec task to run one of the tools to generate
      AssemblyInfo.Shared.cs based on the location of AssemblyInfo.Shared.cs.in
      and some of the other properties.
    -->
  </Target>
</Project>

Содержимое файла VersionInfo.targets может быть просто встроено в файл .csproj, но оно является внешним, потому что я пытаюсь превратить все это в шаблон проекта. Я хочу, чтобы пользователи шаблона могли добавить новый проект в решение, отредактировать файл VersionInfo.targets и запустить сборку.

Проблема в том, что изменение и сохранение файла VersionInfo.targets и перестройка решения не имеют никакого эффекта - файл проекта использует значения из файла .targets, какими они были при открытии проекта. Даже выгрузка и перезагрузка проекта не имеет никакого эффекта. Чтобы получить новые значения, мне нужно закрыть Visual Studio и снова открыть его (или перезагрузить решение).

Как настроить это так, чтобы конфигурация была внешней по отношению к файлу .csproj и не кэшировалась между сборками?

Ответы [ 4 ]

5 голосов
/ 02 июня 2011

Я только что ответил на вопрос, похожий на этот вопрос.

Как отключить кэширование определений сборки в Visual studio

Надеюсь, это актуально и для вашей проблемы.

3 голосов
/ 25 мая 2010

Насколько я знаю, ты не можешь. Visual Studio не использует «настоящий» MSBuild, он использует внутренний механизм сборки, который ведет себя очень похоже на MSBuild.exe, но все же имеет некоторые тонкие различия. Этот механизм сборки кэширует цели, поэтому вам нужно перезапустить VS, как только вы что-то измените. Я полагаю, что это даже где-то задокументировано, и нет известного обходного пути (я искал его около года назад и ничего не нашел).

Возможно, вы могли бы заставить VS перезагружать цели через VS API - поэтому вам придется создать (или найти) специальное дополнение для этого.

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

Upd.

Это то, что я сделал некоторое время назад. MSBuild вызывает внешний инструмент через Exec с WorkingDirectory = "$ (SolutionDir)", инструмент "знает" все соглашения об именах файлов, расположениях и т. Д., Поэтому для выполнения работы достаточно рабочего каталога. Разные данные конфигурации хранятся в конфигурации внешнего инструмента, поэтому проблем с кэшированием нет.

Также взгляните на этот вопрос о чтении элементов из файла. Я полагаю, это лучше соответствует вашим потребностям.

2 голосов
/ 21 декабря 2010

У меня был некоторый прерывистый успех, изменив файл проекта, включая пользовательский файл msbuild, и сделав его недействительным, затем перезагрузив проект, оставив его выгруженным, затем исправив файл проекта и перезагрузив.

Иногда это работает, иногда нет, но лучше, чем перезапуск Visual Studio.

1 голос
/ 16 февраля 2012

Если вам нужен быстрый и грязный способ исправить это, вы можете просто перезагрузить решение (через https://stackoverflow.com/a/6877056/182371).

Вы можете сделать это, либо закрыв-открыв файл решения, либо нажав Сохранить во внешнем редакторе (тогда, когда вы вернетесь к VS, появится вопрос, хотите ли вы перезагрузить компьютер).

...