如何在Visual Studio中关闭构建定义的缓存

时间:2011-02-07 08:18:16

标签: visual-studio msbuild

在项目文件中,我导入了我自己的目标文件

<Import Project="Build\CopyDependencies.target" />

以后我从目标文件中调用目标

<CallTarget Targets="CopyDependencies" UseResultsCache="false" />

如果我编辑CopyDependencies.target文件,我必须重新加载整个解决方案,然后只有对CopyDependencies.target的更改才会生效。我相信它是Visual Studio中的某种构建定义缓存?如果是,也许它可以关闭?

5 个答案:

答案 0 :(得分:14)

谢谢@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>

问题解决了

答案 1 :(得分:9)

我不知道如何禁用VS缓存,但是我可能有一个解决方法,允许您编辑构建目标而无需重新加载解决方案。

您可以使用proj文件中的MSBuild任务来调用将CopyDependencies.target文件复制到CopyDependencies。[RandomNumber] .target的包装器目标,然后在新创建的文件中调用CopyDependencies目标,最后将其删除。

这会强制VS在每次调用时重新加载目标,因为文件名不同。

以下是一个例子:

myProject.proj

将其添加到AfterBuild目标:

<MSBuild Projects="Wrapper.target" Targets="MyWrappedTarget" UnloadProjectsOnCompletion="true"/>

Wrapper.target

这里我们有一个目标 - 在构建时 - 复制真实的目标文件并在其中调用所需的构建目标(我使用了仅在MSBuild 4.0中可用的内联c#任务):

    <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中重新加载解决方案。

答案 2 :(得分: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命令,也不会缓存文件。

快乐的编码!

答案 3 :(得分:3)

这是一个根本不需要任何MSBuild脚本的解决方案。

我注意到卸载和重新加载项目并没有绕过缓存,但关闭并重新打开解决方案。此外,如果注意到.sln文件已更改,Visual Studio将提示您重新加载解决方案。最后,this superuser question解释了如何在Windows中触摸文件。

将这些放在一起,我添加了一个Visual Studio外部工具来触摸当前的解决方案文件。以下是:

  1. 选择工具&gt;外部工具......
  2. 单击“添加”按钮添加新工具。
  3. 设置属性如下:
    • 标题:重新加载解决方案
    • 命令:cmd.exe
    • 参数:/ c copy&#34; $(SolutionFileName)&#34; +&gt; nul
    • 初始目录:$(SolutionDir)
    • 并启用“使用输出”窗口
  4. 单击“确定”关闭“外部工具”窗口
  5. 现在,如果您对MSBuild文件进行了更改,只需选择TOOLS&gt;重新加载解决方案和所有构建文件将被重新加载。

    我使用的是Windows 7 64位和Visual Studio 2012 Express for Windows桌面。

答案 4 :(得分:0)

在运行MSBuild之前,我运行它来清除下载缓存:

call "%VS120COMNTOOLS%vsvars32.bat"
echo Clear download cache
gacutil -cdl