如何防止在项目构建期间外部MSBuild文件被Visual Studio缓存?

15

我在解决方案中有一个项目,最开始是一个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文件且在构建之间不被缓存?


可能是如何在Visual Studio中关闭构建定义缓存的重复问题。 - yoyo
另一个可能的重复问题:https://dev59.com/zEvSa4cB1Zd3GeqPcCjS - Matt Ruwe
4个回答

5

3
据我所知,你不能这样做。 Visual Studio并没有使用“真正的”MSBuild,而是使用了一个内部构建引擎,与MSBuild.exe非常相似,但仍有一些微妙的差异。这个构建引擎缓存了目标,因此你必须在更改后重新启动VS。我相信,这甚至已经有文档记录了,而且没有已知的解决方法(我大约一年前搜索了一下,什么都没找到)。
你可能可以通过VS API强制VS重新加载目标 - 因此,你将不得不创建(或查找)一个自定义插件来完成这个任务。
另一个选择是使用除.targets文件以外的其他东西来存储你的配置。例如,你可以使用纯文本文件,并使用MSBuild解析它(虽然不太优雅,但应该能行)。
更新。
我曾经做过这样的事情。MSBuild通过Exec调用一个外部工具,WorkingDirectory="$(SolutionDir)",这个工具“知道”所有关于文件名、位置等的惯例,因此工作目录足以完成工作。杂项配置数据存储在外部工具的配置中,因此不会出现缓存问题。
此外,请查看关于从文件中读取项目的这个问题。我认为,那更适合你的需求。

谢谢,@VladV。外部配置选项听上去像是一个可能性。不过我对MSBuild完全是个新手 - 你能推荐一些读取外部文件属性的参考材料吗? - Damian Powell
MSBuild参考资料:http://msdn.microsoft.com/zh-cn/library/0k6kkbsd.aspx。MSBuild社区任务(一些有用的MSBuild扩展):http://msbuildtasks.tigris.org/。 - VladV
我已经为MSBuild实现了一种依赖关系解析器,并且它使用了一些外部配置,但我现在手头没有代码。我会尽量在几个小时内为您找到一些示例。 - VladV
抱歉,昨天我没能查看这些内容。我刚刚更新了我的答案。 - VladV

2

通过修改项目文件并将其设置为无效,然后重新加载该项目文件并使其保持未加载状态,然后修复项目文件并重新加载,我有时能偶尔成功。

这种方法有时有效,有时无效,但比重新启动Visual Studio要好。


以下黑科技似乎有效:从解决方案中删除项目(右键单击项目,“删除”)。然后再次添加它(右键单击解决方案,“添加” - “现有项目...”,浏览到 csproj 文件)。 - Jeppe Stig Nielsen

1
如果您需要快速且简单的方法来解决问题,您可以通过重新加载解决方案(通过https://dev59.com/u1nUa4cB1Zd3GeqPdb5m#6877056)来实现。
您可以通过关闭-打开解决方案文件或在外部编辑器中点击保存来完成此操作(然后当您回到VS时,它会询问您是否要重新加载)。

缓存可以在重新加载后保留(在磁盘上更新“.sln”文件后),因此即使重新加载,问题仍然存在。 - Jeppe Stig Nielsen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接