Visual Studio 2017 以前的旧格式的 csproj Import 进来的 targets 文件有时不能正确计算属性(PropertyGroup)和集合(ItemGroup)
我在之前的博客中有教大家如何编写 NuGet 工具包,其中就有编写 .targets 文件。
我在实际的使用中,发现 Visual Studio 2017 带来的含 Sdk 的新 csproj 格式基本上没有多少坑;然而旧的 csproj 文件却总是不能完美的运行,总是出错。关键是,不是每台电脑都出错,不是每个时机都出错。
本文将讲一些坑。
本文的前置知识
你可能需要了解 csproj 文件的格式和编译过程,才可能读懂本文,所以需要先阅读:
问题
下面的代码来自 SourceFusion 项目的早期版本。
这是一个 .targets 文件,项目安装此 NuGet 包之后就会自动 Import 这个 targets 文件。
<Project>
<PropertyGroup>
<_DefaultSourceFusionWorkingFolder Condition="'$(_DefaultSourceFusionWorkingFolder)' == ''">obj\$(Configuration)\</_DefaultSourceFusionWorkingFolder>
<SourceFusionWorkingFolder Condition="'$(SourceFusionWorkingFolder)' == ''">$(_DefaultSourceFusionWorkingFolder)</SourceFusionWorkingFolder>
<SourceFusionToolsFolder>$(SourceFusionWorkingFolder)SourceFusion.Tools\</SourceFusionToolsFolder>
<SourceFusionGeneratedCodeFolder>$(SourceFusionWorkingFolder)SourceFusion.GeneratedCodes\</SourceFusionGeneratedCodeFolder>
</PropertyGroup>
<Target Name="_SourceFusionCreateDirectories" BeforeTargets="_SourceFusionWriteCompilingArgs;_SourceFusionWriteFilterArgs">
<ItemGroup>
<SourceFusionDirectory Include="$(SourceFusionWorkingFolder)" />
<SourceFusionDirectory Include="$(SourceFusionToolsFolder)" />
<SourceFusionDirectory Include="$(SourceFusionGeneratedCodeFolder)" />
</ItemGroup>
<MakeDir Directories="@(SourceFusionDirectory)" ContinueOnError="false" />
</Target>
</Project>
代码的解读如下:
- 创建了一个私有属性
_DefaultSourceFusionWorkingFolder,三个公有属性SourceFusionWorkingFolder、SourceFusionToolsFolder、SourceFusionGeneratedCodeFolder。 - 在编译期间,执行一个私有的 Target,收集所有收集到的文件夹,形成一个
SourceFusionDirectory集合。然后将集合中的所有字符串视为文件夹,创建这几个文件夹。
在新的有 Sdk 的 csproj 中,这个 targets 文件的执行没有问题。但是,对于旧的 csproj 来说,就经常出现这几个属性为空或者部分为空的情况。额外的,就算修改这个文件,上面的属性也不会生效。
不过,如果使用命令行进行编译,这个却又是生效的。
原因
究其原因,这是 MSBuild 对项目文件(csproj)的解析和 Visual Studio 对项目文件的解析是不同的。命令行使用的是 MSBuild 解析 csproj,而 Visual Studio 使用的是 VSProjectSystem。
对于 VSProjectSystem 来说,Project 根节点下的 PropertyGroup 和 ItemGroup 对不会更新。有时清除 Visual Studio 的项目缓存可以解决这个问题,但有时清除也不能解决。
真实的原因我并没有调查出来。但以上代码在大多数开发者的 Visual Studio 中是可以正常使用的,但有少数开发者使用这个会出现错误(没有创建任何文件夹)。
解决办法
既然问题出在 MSBuild 和 VSProjectSystem 对属性和集合处理的不同,那么我就不要创建动态的集合,而是在 Target 内部编写属性和集合。
在 Target 内部的属性和集合将在编译期间进行计算,而不是在 Visual Studio 打开的时候就计算好。于是我们每次编译的时候都可以获得最新的属性和集合的值。
衍生知识
旧格式的 csproj 是不会自动计算属性和集合的变更的,这也是为什么项目文件改变的时候,Visual Studio 需要重新加载项目才可以正常显示和编译项目。同时,如果编辑旧格式的 csproj 文件,也需要先卸载掉项目才可以。而新格式的 csproj 是可以直接编辑而不需要卸载项目的,同时如果被外部改变,也不需要重新加载项目,而是可以直接计算出来新的属性和集合。
Visual Studio 2017 以前的旧格式的 csproj Import 进来的 targets 文件有时不能正确计算属性(PropertyGroup)和集合(ItemGroup)的更多相关文章
- 用于Azure功能的Visual Studio 2017工具
今天我们很高兴地宣布发布第一个预览的Visual Studio 2017工具的Azure功能.这个预览介绍了一些令人兴奋的变化,我们以前的版本.此外,除了支持Visual Studio 2017之外, ...
- Visual Studio 2017 怎么将自动生成属性设置为旧版格式
工具:Visual Studio 2017 1.点击工具,进入选项 2.选项窗口左侧找到C#--代码样式,点击 3.找到表达式首选项中:使用属性的表达式主体.使用索引器的表达式主体和使用访问器的表达式 ...
- 最强 IDE Visual Studio 2017 正式版发布
Visual Studio 2017 正式版发布,该版本不仅添加了实时单元测试.实时架构依赖关系验证等新特性,还对许多实用功能进行了改进,如代码导航.IntelliSense.重构.代码修复和调试等等 ...
- Visual Studio 2017正式版发布全纪录
又是一年发布季,微软借着Visual Studio品牌20周年之际,于美国太平洋时间2017年3月7日9点召开发布会议,宣布正式发布新一代开发利器Visual Studio 2017.同时发布的还有 ...
- Visual Studio 2017开发环境的安装
Visual Studio 2017是微软为了配合.NET战略推出的IDE开发环境,同时也是目前开发C#程序最新的工具,本节以Visual Studio 2017社区版的安装为例讲解具体的安装步骤. ...
- Visual Studio 2017 Enterprise (15.3)
版本15.3更新在用户离线下载时更加人性化,包含了进度显示,下载出错可以输入R,进行下载的重新尝试,并在当前下载框下继续下载为完成的作业,结合 --layout 参数的离线文件的检查和修复,并且在下载 ...
- Visual Studio 2017 发布 15.5 版本,百度网盘离线安装包下载。
Visual Studio 2017 15.5 版本已正式发布,同时发布的还有 Visual Studio for Mac 7.3 .此次更新包含主要性能改进,新特性以及 bug 修复.发行说明中文版 ...
- Visual Studio 2017 Enterprise 发布 15.4 版本,离线安装包百度网盘下载。
Visual Studio 2017 于2017年10月13日发布 15.4 版本.该版本包含多项生产力改进,支持 .NET Standard 2.0 ,并且可以开启 Xamarin Live Pla ...
- Visual Studio 2017 Enterprise 发布 15.3.3 版,附离线安装包百度网盘下载。
Visual Studio 2017 Enterprise 发布 15.3.3 版,附离线安装包百度网盘下载. Visual Studio 2017 Enterprise 更新至 15.3.3 ,本安 ...
随机推荐
- angular5 表单元素 checkbox radio 组讲解
一.checkedbox 1.ngModel绑定方式 <input [(ngModel)]="item.checked" value="item.checked&q ...
- angular5 ng-bootstrap和ngx-bootstrap区别
https://angular.cn/resources ngx-bootstrap 安装: npm install ngx-bootstrap --save 再引入css <link href ...
- php将中文符号全部替换为英文符号
php将中文符号全部替换为英文符号 一.总结 一句话总结:可以用简单替换和规律替换 简单替换 str_replace() 规律替换 均相差 65248 方法一:简单替换(php代码) $val1=st ...
- springboot 解决 The bean 'userRepository', defined in null, could not be registered. A bean with that name has already been defined in file XXX and overriding is disabled.
1.springboot 启动时报错: 2019-02-20 14:59:58.226 INFO 10092 --- [ main] c.f.s.SpringbootssmApplication : ...
- Jaccard similarity(杰卡德相似度)和Abundance correlation(丰度相关性)
杰卡德距离(Jaccard Distance) 是用来衡量两个集合差异性的一种指标,它是杰卡德相似系数的补集,被定义为1减去Jaccard相似系数.而杰卡德相似系数(Jaccard similarit ...
- CSS#Flex-box, border-size, onresize() event, Media Queries
Flexbox Pseudo-classes box-sizing: border-box HTML DOM event resize() @media Queries: 根据一些css条件,触发一 ...
- Eclipse重命名项目名后如何彻底修改工程名
背景:在Eclipse中当我们修改了一个Web项目名称后,在再次运行该项目,发现使用新的名称无法正常的浏览,而用旧的名称去可以 解决方案: 1:修改该项目目录下:.project文件 <?xml ...
- Oracle12c 中RAC功能增强新特性之ASM&Grid
1. 自动存储管理(ASM)方面的增强 1.1. Flex ASM 在典型的网格架构安装中,每个节点有自己的ASM实例运行并扮演该节点上数据库的存储容器的角色,对这种安装配置,存在单点失败的 ...
- zabbix LLD 自定义脚本
一 前言 二 懒人必备zabbix监控之 LLD (low level discovery) 本次的教程是我想监控kafka的消费情况,举个栗子 [root@VM_0_98_centos bin]# ...
- bootstrap滑动开关插件使用
下载和演示插件地址 需要引入的css和js <link rel="stylesheet" type="text/css" href="/css/ ...