更新和包含有什么区别?
据this document:
用法:
Include 属性 => 包含在项目列表中的文件或通配符。
Update 属性 => 使您能够修改使用 glob 包含的文件的元数据。
工作范围:
Include attribute:
1. 适用于normal .net framewrok(非sdk 格式)、.net core and .net standard(sdk 格式)以及C++ 项目...
2.在多个VS版本中使用(据我所知,从VS2010到VS2019)
3.Include 甚至可以在 Targets 的 ItemGroup 中使用
Update attribute:
1.适用于 .net 核心项目
2.VS2017及更高版本可用
3.在Target内的ItemGroup中使用时不支持
测试和结果:
不包含 c.txt 时的第一次测试:
<ItemGroup>
<DoSth Include="a.txt"/>
<DoSth Include="b.txt"/>
<DoSth Update="c.txt" Metadata="test"/>
</ItemGroup>
<Target Name="MyTest" AfterTargets="build">
<Message Text="@(DoSth)" Importance="high"/>
</Target>
<!--The output is a.txt and b.txt, no c.txt.-->
包含 c.txt 时的第二次测试:
<ItemGroup>
<DoSth Include="a.txt"/>
<DoSth Include="b.txt"/>
<DoSth Include="c.txt" Metadata="original"/>
<DoSth Update="c.txt" Metadata="test"/>
</ItemGroup>
<Target Name="MyTest" AfterTargets="build">
<Message Text="@(DoSth)" Importance="high"/> <!--The output files are a.txt,b.txt and c.txt.-->
<Message Text="%(DoSth.Identity)+%(DoSth.Metadata)" Importance="high"/> <!--The output Metadata of c.txt is test instead of original-->
</Target>
所以很明显Update attribute 仅用于更新一个项目的元数据。它没有包含某些文件的功能。只有当一个文件已包含在一个项目中时,它才会起作用。
澄清在.net core 控制台中使用Update + appsettings.json 和
asp.net core网络应用:
在 Asp.net 核心网络应用程序中:
如果您创建一个新的asp.net core web 项目,默认情况下您可以在解决方案资源管理器中看到appsettings.json 文件。但是如果您阅读xx.csproj 则无法在其中找到定义,定义未明确显示在 xx.csproj 中用于 sdk 格式。
在这种情况下,如果我们使用像<None Include="appsettings.json" CopyToOutputDirectory="Always" /> 这样的脚本,它总是可以将该文件复制到输出。
但是对于脚本<None Update="appsettings.json" CopyToOutputDirectory="PreserveNewest" />,它只有在项目文件中没有<Content xxx="appsettings.json"...>这样的语句时才有效。
我建议您通过 VS UI 来执行此操作,而不是手动编辑 xx.csproj。我们可以更改Property Window中的Build Action and Copy To Output设置:
如果我们将build action设置为None,将Copy to Output设置为Copy if Never的Copy if Never,在xx.csproj中我们可以找到:
<ItemGroup>
<Content Remove="appsettings.json" />
</ItemGroup>
<ItemGroup>
<None Include="appsettings.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
所以 VS 为此使用 None+Include 。根据以上所有,我建议您在项目中使用None+Include 而不是None+Update。此外,最推荐的方法是在 VS IDE 中通过 UI 控制复制行为,而不是手动编辑。希望以上所有帮助:)
更新1:
我们可以在项目文件中添加这个脚本来输出关于在csproj中没有显示的None Items和Content Items的信息:
<Target Name="TrytoFindDefinitionsNowShown" AfterTargets="build">
<Message Text="None: @(None)" Importance="high"/>
<Message Text="Content: @(Content)" Importance="high"/>
</Target>
更新2:
我刚刚做了一些测试,发现即使在 VS 的 .net core 控制台项目中,虽然 csproj 中没有定义,但更新可以工作。奇怪的?
最后我发现这是因为该定义在 csproj 文件中隐藏或不显示,实际上当您在项目中有一个 appsettings.json 文件时,您已经定义了一个 <None Include="appsettings.json"... (有时 Content+include,ikt 取决于您添加该文件的方式),虽然这在 csproj 中无效,但请看我的截图:
这就是为什么 Update 可以用于复制行为,尽管它用于修改元数据。在我们使用更新之前,已经存在 None+Include+Appsettings.json 的定义,尽管 csproj 中没有显示。 (对于sdk格式)
更新3:
我对 Update1 中的脚本做了一些小改动,以显示 <None Include="appsettings.json"> 的元数据。
所以在.net核心控制台项目中,appsettings.json文件默认是
<None Include="appsettings.json" CopyToOutputDirectory="Never" />
这就是为什么None+Include+Always(覆盖)和None+Update+Always or PreserveNewest(修改元数据)都适用于复制行为。它可以描述为什么默认情况下该文件不会被复制,即使 VS 在某处隐藏了None+Include 定义。因为CopyToOutputDirectory默认设置为从不。