如何防止在项目生成期间(由 Visual Studio)缓存外部 MSBuild 文件?
我的解决方案中有一个项目,它最初是一个 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 文件外部并且不在构建之间缓存?
I have a project in my solution which started life as a C# library project. It's got nothing of any interest in it in terms of code, it is merely used as a dependency in the other projects in my solution in order to ensure that it is built first. One of the side-effects of building this project is that a shared AssemblyInfo.cs is created which contains the version number in use by the other projects.
I have done this by adding the following to the .csproj file:
<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" />
The referenced file, VersionInfo.targets, contains the following:
<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>
The contents of the VersionInfo.targets file could simply be embedded within the .csproj file but it is external because I am trying to turn all of this into a project template. I want the users of the template to be able to add the new project to the solution, edit the VersionInfo.targets file, and run the build.
The problem is that modifying and saving the VersionInfo.targets file and rebuilding the solution has no effect - the project file uses the values from the .targets file as they were when the project was opened. Even unloading and reloading the project has no effect. In order to get the new values, I need to close Visual Studio and reopen it (or reload the solution).
How can I set this up so that the configuration is external to the .csproj file and not cached between builds?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
我刚刚回答了一个类似的问题。
如何关闭在 Visual studio 中构建定义
希望它也与您的问题相关。
I've just answered what appears to be a similar question on this.
How to turn off caching of build definitions in Visual studio
Hopefully it's relevant your issue too.
据我所知,你不能。
Visual Studio 没有使用“真正的”MSBuild,它使用内部构建引擎,其行为与 MSBuild.exe 非常相似,但仍然存在一些细微的差异。该构建引擎会缓存目标,因此一旦更改某些内容就必须重新启动 VS。我相信,它甚至在某个地方有记录,并且没有已知的解决方法(我大约一年前搜索过它,但什么也没找到)。
您可能会强制 VS 通过 VS API 重新加载目标 - 因此,您必须创建(或查找)自定义附加组件来执行此操作。
另一种选择是使用 .targets 文件以外的其他文件来存储配置。例如,您可以使用纯文本文件并使用 MSBuild 解析它(不是那么优雅,但它应该可以工作)。
更新。
这就是我前段时间所做的。 MSBuild 通过 Exec 使用 WorkingDirectory="$(SolutionDir)" 调用外部工具,该工具“知道”有关文件名、位置等的所有约定,因此工作目录足以完成工作。各种配置数据存储在外部工具的配置中,因此缓存没有问题。
另外,请查看关于从文件中读取项目的此问题 。我想,这更适合您的需求。
As far as I know, you can't.
Visual Studio is not using 'real' MSBuild, it uses an internal build engine that behaves very similar to MSBuild.exe, but still have some subtle differences. This build engine caches the targets, so you have to restart VS once you change something. I believe, it is even documented somewhere, and there is no known workaround (I searched for it about a year ago and found nothing).
You could possibly force the VS to reload the targets via VS API - so, you'll have to create (or find) a custom add-on to do this.
Another option is to use something other than .targets file to store your configuration. For instance, you could use a plain text file and parse it with MSBuild (not that elegant, but it should work).
Upd.
That's what I did some time ago. MSBuild calls an external tool via Exec with WorkingDirectory="$(SolutionDir)", the tool "knows" all the conventions about file names, locations etc., so a working directory is enough to get the job done. Miscellaneous configuration data is stored in the external tool's config, so no problems with caching.
Also, have a look at this question about reading items from a file. I suppose, that better suites your needs.
我通过修改项目文件(包括自定义 msbuild 文件并使其无效,然后重新加载项目,让它保持卸载状态,然后修复项目文件并重新加载)取得了一些间歇性的成功。
有时有效,有时无效,但比重新启动 Visual Studio 更好。
I had some intermittent success by modifying the project file including the custom msbuild file and making it invalid, then reloading the project, let it stay unloaded, then fixing the project file and reloading.
Sometimes it works, sometimes it doesn't, but better than restarting Visual Studio.
如果您需要一种快速而肮脏的方法来修复它,您可以简单地重新加载解决方案(通过 https://stackoverflow.com/a/ 6877056/182371)。
您可以通过关闭-打开解决方案文件或在外部编辑器中单击“保存”来完成此操作(然后当您返回 VS 时,它会询问您是否要重新加载)。
If you need a quick and dirty way to fix it, you may simply reload the solution (via https://stackoverflow.com/a/6877056/182371).
You can do it either by closing-opening the solution file or by hitting Save in an external editor (then when you come back to VS it will asko if you want to reload).