Как отключить кэширование определений сборки в Visual Studio
В файле проекта я импортирую свой целевой файл
<Import Project="Build\CopyDependencies.target" />
а затем я вызываю цель из этого целевого файла
<CallTarget Targets="CopyDependencies" UseResultsCache="false" />
Если я отредактирую файл CopyDependencies.target, я должен перезагрузить целое решение, и только потом изменения в CopyDependencies.target вступят в силу. Я считаю, что это кеширование определений построений в Visual Studio? Если да, возможно, его можно отключить?
Ответы
Ответ 1
Спасибо @KazR
Ниже приведено меньшее решение, которое вы можете вставить в свой файл .csproj.
<Target Name="AfterBuild">
<PropertyGroup>
<TempProjectFile>Build.$([System.Guid]::NewGuid()).proj</TempProjectFile>
</PropertyGroup>
<Copy SourceFiles="Build.proj" DestinationFiles="$(TempProjectFile)" />
<MSBuild Projects="$(TempProjectFile)" />
<ItemGroup>
<TempProjectFiles Include="Build.????????-????-????-????-????????????.proj"/>
</ItemGroup>
<Delete Files="@(TempProjectFiles)" />
</Target>
Проблема решена
Ответ 2
Я не знаю, как вы могли бы отключить кеш VS, однако у меня может быть обходное решение, которое позволит вам редактировать цель сборки без необходимости перезагрузки решения.
Вы можете использовать задачу MSBuild в своем файле proj для вызова объекта-оболочки, который копирует ваш файл CopyDependencies.target в CopyDependencies. [RandomNumber].target, затем вызывает ваш экземпляр CopyDependencies во вновь созданном файле и, наконец, удаляет его.
Это заставит VS перезагрузить цель при каждом вызове, поскольку имя файла отличается.
Вот пример:
myProject.proj
Добавьте это в цель AfterBuild:
<MSBuild Projects="Wrapper.target" Targets="MyWrappedTarget" UnloadProjectsOnCompletion="true"/>
Wrapper.target
Здесь у нас есть цель, которая будет - во время сборки - скопировать реальный файл цели и вызвать нужную цель сборки внутри него (я использовал задачу inline С#, которая доступна только в MSBuild 4.0):
<UsingTask TaskName="RandomNumber" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Number ParameterType="System.Int32" Output="true"/>
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<!-- CDATA -->
Random rndGenerator = new Random();
Number = rndGenerator.Next(Int32.MaxValue);
<!-- CDATA -->
</Code>
</Task>
</UsingTask>
<Target Name="MyWrappedTarget">
<Message Text="MyWrappedTarget target called"/>
<RandomNumber>
<Output TaskParameter="Number" PropertyName="FileNumber"/>
</RandomNumber>
<PropertyGroup>
<CopiedTarget>inner.test.$(FileNumber).target</CopiedTarget>
</PropertyGroup>
<Copy SourceFiles="inner.test.target" DestinationFiles="$(CopiedTarget)"/>
<MSBuild Projects="$(CopiedTarget)" Targets="_innerTestTarget"/>
<Delete Files="$(CopiedTarget)"/>
</Target>
inner.test.target
Здесь содержится реальная цель сборки, которую вы хотите выполнить, в этом примере это простая копия файла.
<Target Name="_innerTestTarget">
<Message Text="This is a inner test text message"/>
<Copy SourceFiles="x.txt" DestinationFiles="x1.txt"/>
</Target>
Это не готово к производству, но, надеюсь, иллюстрирует мою мысль.
С помощью этого (слегка запутанного) процесса вы можете изменить файл inner.test.target, не перезагружая решение в VS.
Ответ 3
У меня есть другое решение, не связанное с временными файлами:
Файл Include.targets:
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Target Name="Foobar">
<Copy SourceFiles="test.source" DestinationFiles="testFoobar.dest" />
</Target>
</Project>
Файл проекта:
....
<Target Name="BeforeBuild">
<Exec Command="$(MSBuildToolsPath)\MSBuild.exe Include.targets /t:Foobar" ContinueOnError="false" />
</Target>
....
В этом случае VS не распознает команду MSBuild и не кэширует файл.
счастливое кодирование!
Ответ 4
Вот решение, которое вообще не требует каких-либо скриптов MSBuild.
Я заметил, что разгрузка и перезагрузка проекта не обойти кеш, но закрытие и повторное открытие решения. Кроме того, Visual Studio предложит вам перезагрузить решение, если оно замечает, что файл .sln был изменен. И, наконец, этот вопрос суперпользователя объясняет, как прикасаться к файлу в Windows.
Объединяя это, я добавил внешний инструмент Visual Studio, чтобы коснуться текущего файла решения. Вот как:
- Выберите TOOLS > External Tools...
- Нажмите кнопку "Добавить", чтобы добавить новый инструмент.
- Задайте свойства следующим образом:
- Название: Reload Solution
- Команда: cmd.exe
- Аргументы:/c copy "$ (SolutionFileName)" + > nul
- Начальная директория: $(SolutionDir)
- и включите окно "Использовать выходные данные"
- Нажмите "ОК", чтобы закрыть окно "Внешние инструменты"
Теперь, если вы внесли изменения в файлы MSBuild, просто выберите TOOLS > Reload Solution и все ваши файлы сборки будут перезагружены.
Я использую Windows 7 64-bit и Visual Studio 2012 Express для Windows Desktop.
Ответ 5
Перед запуском MSBuild
я запустил это, чтобы очистить кеш загрузки:
call "%VS120COMNTOOLS%vsvars32.bat"
echo Clear download cache
gacutil -cdl