title author date CreateTime categories
Roslyn 在项目文件使用条件判断
lindexi
2019-7-3 17:7:32 +0800
2018-8-3 20:2:38 +0800
Roslyn MSBuild 编译器

本文告诉大家如何在项目文件通过不同的条件使用不同的方法运行

本文是 手把手教你写 Roslyn 修改编译 的文章,在阅读本文之前,希望已经知道了大多数关于 msbuild 的知识

为了告诉大家如何使用判断,需要创建一个简单的程序来写,这里创建一个 dotnet core 控制台项目,如果还没安装 dotnet core 可以到 dotnet sdk 2.1.300 winx64-CSDN下载

从 VisualStudio 安装文件夹打开开发人员工具命令行,打开这个是因为如果没有将 msbuild 加入到环境变量,就需要使用这个方法来调用 msbuild 调用 msbuild 的原因是为了编译可以看到输出。

Target 如果用 Message 的输出,除了设置为错误,其他的输出在 VisualStudio 的输出是无法看到的,只能通过 msbuild 才可以看到。

打开开发人员工具,先进入到刚才创建的项目所在的文件夹,然后执行msbuild就可以看到输出

C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi>msbuild
用于 .NET Framework 的 Microsoft (R) 生成引擎版本 15.7.180.61344
版权所有(C) Microsoft Corporation。保留所有权利。 生成启动时间为 2018/8/3 20:05:47。
节点 1 上的项目“C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi\RaskerYadeacorLalmi.csproj”(默认目标)。
GenerateTargetFrameworkMonikerAttribute:
正在跳过目标“GenerateTargetFrameworkMonikerAttribute”,因为所有输出文件相对于输入文件而言都是最新的。
CoreGenerateAssemblyInfo:
正在跳过目标“CoreGenerateAssemblyInfo”,因为所有输出文件相对于输入文件而言都是最新的。
CoreCompile:
正在跳过目标“CoreCompile”,因为所有输出文件相对于输入文件而言都是最新的。
StanalurJikecair:
123
GenerateBuildDependencyFile:
正在跳过目标“GenerateBuildDependencyFile”,因为所有输出文件相对于输入文件而言都是最新的。
GenerateBuildRuntimeConfigurationFiles:
正在跳过目标“GenerateBuildRuntimeConfigurationFiles”,因为所有输出文件相对于输入文件而言都是最新的。
CopyFilesToOutputDirectory:
RaskerYadeacorLalmi -> C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi\bin\Debug\netcoreapp2.0\RaskerYadeac
orLalmi.dll
已完成生成项目“C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi\RaskerYadeacorLalmi.csproj”(默认目标)的操作。 已成功生成。
0 个警告
0 个错误

上面代码创建的是 RaskerYadeacorLalmi 项目,在这个项目所在的文件夹进行编译,这个项目是新创建的,只是在项目上写了下面代码

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile">
<Message Text="123"></Message>
</Target>

这是一个空白的Target,一个Target有一个 Name 和一个属性告诉在什么时候运行这个Target在这个Target里使用Message,就可以在编译时看到下面代码

StanalurJikecair:
123

如果重新运行msbuild会发现有很多都是跳过,具体请看每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译 - walterlv

C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi>msbuild
用于 .NET Framework 的 Microsoft (R) 生成引擎版本 15.7.180.61344
版权所有(C) Microsoft Corporation。保留所有权利。 生成启动时间为 2018/8/3 20:05:47。
节点 1 上的项目“C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi\RaskerYadeacorLalmi.csproj”(默认目标)。
GenerateTargetFrameworkMonikerAttribute:
正在跳过目标“GenerateTargetFrameworkMonikerAttribute”,因为所有输出文件相对于输入文件而言都是最新的。
CoreGenerateAssemblyInfo:
正在跳过目标“CoreGenerateAssemblyInfo”,因为所有输出文件相对于输入文件而言都是最新的。
CoreCompile:
正在跳过目标“CoreCompile”,因为所有输出文件相对于输入文件而言都是最新的。
StanalurJikecair:
warning:123
GenerateBuildDependencyFile:
正在跳过目标“GenerateBuildDependencyFile”,因为所有输出文件相对于输入文件而言都是最新的。
GenerateBuildRuntimeConfigurationFiles:
正在跳过目标“GenerateBuildRuntimeConfigurationFiles”,因为所有输出文件相对于输入文件而言都是最新的。
CopyFilesToOutputDirectory:
RaskerYadeacorLalmi -> C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi\bin\Debug\netcoreapp2.0\RaskerYadeac
orLalmi.dll
已完成生成项目“C:\lindexi\github\RaskerYadeacorLalmi\RaskerYadeacorLalmi\RaskerYadeacorLalmi.csproj”(默认目标)的操作。 已成功生成。
0 个警告
0 个错误

如果需要清理,重新编译,可以输入下面命令

msbuild clean

现在可以尝试使用 Conditions 判断条件

使用 Conditions 很多时候都是使用字符串判断,如使用下面代码

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup> <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="$(TargetFramework)=='netcoreapp2.0'">
<Message Text="123"></Message>
</Target>

因为TargetFrameworknetcoreapp2.0 会运行这个 Target ,如果这时修改 TargetFrameworknet45 就不会运行这个代码

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="$(TargetFramework)=='net45'">
<Message Text="123"></Message>
</Target>

如果需要同时判断多个条件,如在 Debug 而且是 net45 就运行,可以使用下面代码

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="'$(Configuration)|$(TargetFramework)'=='DEBUG|net45'">
<Message Text="123"></Message>
</Target>

注意在原来的$(Configuration)是可以不使用引号,但是现在使用了|就需要添加引号,表示这时字符串

实际的|不是语法,可以换为其他的字符,如下面的代码

    <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="'$(TargetFramework)-$(OutputType)'=='netcoreapp2.0-Exe'">
<Message Text="123"></Message>
</Target>

上面代码使用 '$(TargetFramework)-$(OutputType)' 判断

判断不相等

如果需要判断不相同,只需要修改==为不相等

    <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="'$(TargetFramework)'!='net45'">
<Message Text="123"></Message>
</Target>

现在运行msbuild可以看到输出了123如果修改为'$(TargetFramework)'=='net45'就判断不相等

判断大小

除了判断字符串,还可以判断字符串的大小,只能用来判断数值字符串,如果对于 16 进制的字符串,需要使用 0x 开始,如下面代码

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="'60'&gt;'10'">
<Message Text="因为60大于10所以会运行"></Message>
</Target> <Target Name="LamaciswhaJoopisJerall" AfterTargets="CoreCompile" Condition="'60'&gt;='60'">
<Message Text="因为60大于60所以会运行"></Message>
</Target> <Target Name="TasyenatarReresetelRagearsu" AfterTargets="CoreCompile" Condition="'10' &lt; '60'">
<Message Text="因为10小于60所以会运行"></Message>
</Target> <Target Name="FurkeeneLafer" AfterTargets="CoreCompile" Condition="'60'&lt;='60'">
<Message Text="因为60小于等于60所以会运行"></Message>
</Target> <Target Name="JoudewalljeeZeargeaday" AfterTargets="CoreCompile" Condition="'0xAA'&gt;'10'">
<Message Text="如果使用16进制需要使用0x放在字符串最前"></Message>
</Target>

因为使用的文件是 xml 所以需要将会>转换为&gt;,将<转为 &gt; 如果输入的数值是16进制就需要使用 0x 放在开始,下面的代码就会出现下面的错误

  <Target Name="SiscooLecem" AfterTargets="CoreCompile" Condition="'AA'&gt;'10'">
<Message Text="如果使用16进制需要使用0x放在字符串最前"></Message>
</Target>
error MSB4086: 尝试在条件“'AA
'>'10'”中对计算结果为“AA”而不是数字的“AA”进行数值比较

判断文件存在

在条件判可以用 Exists 判断文件 文件夹是否存在

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="Exists('$(OutputPath)')">
<Message Text="$(OutputPath)"></Message>
</Target> <Target Name="ZurwelSowselnu" AfterTargets="CoreCompile" Condition="!Exists('$(OutputPath)')">
<Message Text="$(OutputPath)"></Message>
</Target>

可以看到两个代码的不相同,使用 ! 可以判断为 原来是相同的就返回false,这里的 $(OutputPath) 是存在的,所以编译会输出下面代码

StanalurJikecair:
bin\Debug\netcoreapp2.0\

判断多个条件

除了使用开始的使用 - 等连接多个判断还可以使用 And Or 来判断多个条件,如下面代码

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="Exists('$(OutputPath)') And $(Configuration)=='Debug'">
<Message Text="$(OutputPath)"></Message>
</Target>

同时判断存在输出的文件夹并且在测试下才运行

注意不能使用引号加上 And 如'And',这时 And 会作为字符串

如果使用多个条件,建议使用()包括多个条件,如下面代码,同时进行多个判断

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
<Foo>123</Foo>
</PropertyGroup> <Target Name="StanalurJikecair" AfterTargets="CoreCompile" Condition="(Exists('$(OutputPath)') And $(Configuration)=='Debug') or ($(Foo)=='123')">
<Message Text="$(OutputPath)"></Message>
</Target>

使用的范围

在很多地方都可以使用条件进行判断,如放在任意的PropertyGroup里,如果判断为 false 就不会定义这个属性

  <PropertyGroup>
<OutputType Condition="'德熙' == '逗比'">Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

也可以直接放在PropertyGroup让整个PropertyGroup不定义

  <PropertyGroup Condition="'德熙' == '逗比'">
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

同样可以放在 ItemGroup 里,也可以放在 ItemGroup 控制是否定义

  <ItemGroup>
<Foo Condition="'德熙' == '逗比'" Include="123"></Foo>
</ItemGroup>
  <ItemGroup Condition="'德熙' == '逗比'">
<Foo Include="123"></Foo>
</ItemGroup>

还有上面写的 Target 也可以使用,在 Target 里也可以使用条件

  <Target Name="StanalurJikecair" AfterTargets="CoreCompile">
<Message Condition="'德熙' == '逗比'" Text="$(OutputPath)"></Message>
</Target>

还可以写在 Import 一般在 Import 都需要先判断是否存在文件

  <Import Condition="Exists('../lindexi.txt')" Project="../lindexi.txt"></Import>

特别感谢 HaibaraAi 大佬的阅读

2019-7-3-Roslyn-在项目文件使用条件判断的更多相关文章

  1. Ansible Playbook 使用条件判断语句

    先介绍一下 gather_facts 参数,该参数用于指定在执行任务前,是否先执行 setup 模块获取主机相关信息,以便给后面的任务使用 [root@localhost ~]# ansible 19 ...

  2. Thymeleaf常用语法:条件判断 if、switch case

    if语句条件判断使用th:if,它会判断表达式是否成立,表达式的结果支持boolean.number.character.String及其他类型.满足下面情况,if语句成立:(1) 表达式的结果是数字 ...

  3. Linux shell if条件判断2

    前面介绍linux shell的if判断的语法,现在再补充一点. Linux shell if条件判断1 分支判断结构     if , case   下面两个结构语法,已经在前面有过示例. 结构1: ...

  4. RF之条件判断、初始化清除-4

    条件判断:        rf中用run keyword if 关键字做条件判断,以此来达到类似在python中if ...else...条件判断的功能. 注意:ELSE IF一定都是大写的,不然运行 ...

  5. Java学习之==>条件判断、循环控制

    一.条件判断 1.if-else 示例: /** * 第1种,1个分支 */ public void case1() { int age = 15; if (age > 18) { System ...

  6. C# if中连续几个条件判断

    C# if中连续几个条件判断 1.if (条件表达式1 && 条件表达式2) 当条件表达式1为true时 using System; using System.Collections. ...

  7. js条件判断时隐式类型转换

    Javascript 中,数字 0 为假,非0 均为真 在条件判断运算 == 中的转换规则是这样的: 如果比较的两者中有布尔值(Boolean),会把 Boolean 先转换为对应的 Number,即 ...

  8. 5-3 bash脚本编程之二 条件判断

    1. 条件测试的表达式 1. [ expression ]  :注意这个中括号的前后都有一个空格 2. [[ expression ]] 3. test expression 2.条件判断的类型 1. ...

  9. 第10章 Shell编程(3)_字符处理命令和条件判断

    3. 字符处理命令 3.1 排序命令:sort (1)sort命令:#sort [选项] 文件名 选项 作用 -f 忽略大小写 -n 以数值型进行排序,默认使用字符串型排序 -r 反向排序 -t 指定 ...

随机推荐

  1. 剑指offer——50最长不含重复字符和子字符串

    题目: 请从字符串中找出一个最长的不包含重复字符的子字符串,计算该最长子字符串的长度.假设字符串中只包含’a~z”的字符.例如,在字符串“arabcacfr"中,最长的不含重复字符的子字符串 ...

  2. Java jar文件

    JAR(Java Archive)是基于ZIP文件格式的文件格式. 它用于捆绑Java应用程序或小程序的资源,类文件,声音文件,图像等. 它还提供数据压缩.一个JAR文件作为一种特殊类型的ZIP文件. ...

  3. 什么是Web?

    Web这个词刚开始显得有些泛泛,似乎“冲浪”.“网上存在”以及“主页”等等都和它拉上了一些关系.甚至还有一种“Internet综合症”的说法,对许多人狂热的上网行为提出了质疑.我们在这里有必要作一些深 ...

  4. Hbase时间同步

    如果Hbase的时间没有同步,启动主节点会起来,子节点的regionServer就不会起来. 错误日志如下: aused by: org.apache.hadoop.hbase.ipc.RemoteW ...

  5. Educational Codeforces Round 56 D - Beautiful Graph

    ​题目大意: 在给定的一个图中(可能不连通) 给每个点赋值1.2.3 使得一条边上的两个端点点权相加为奇数 求方案数 一条满足条件的路径上的点权必为一奇一偶交替 偶数只有2 奇数有1.3 若位于1.3 ...

  6. 2018 最新 spring boot 整合 swagger2 (swagger2 版本 2.8.0)

    好久没上了, 看到又有人回复了. 我就来修改一下. 修改时间  2018年5月16日 这回给你上全新版本. 至发稿时间,所有的包都是新版. 注意: 高版本需要添加  jaxb-api 包, 否则会报错 ...

  7. ArcGis Python常用脚本

    ArcGis Python脚本——ArcGIS 中使用的 Python 是什么版本 ArcGis Python脚本——批量添加字段 ArcGis Python脚本——批量删除字段 ArcGis Pyt ...

  8. add new color number to the color drop down in enovia PLM

    Ticket description:A55482L Ticket attachment: Open the attached page 2. Open the internationalizing ...

  9. 2018-9-30-dotnet-core-通过修改文件头的方式隐藏控制台窗口

    title author date CreateTime categories dotnet core 通过修改文件头的方式隐藏控制台窗口 lindexi 2018-09-30 18:36:43 +0 ...

  10. 01_ESP8266 NONO_SDK 创建工程模板

    参考:https://wiki.ai-thinker.com/ai_ide_use  , 仅作为学习笔记. 一.关于报错 注意:Eclipse 只是一个代码编写工具,它并不能读取 makefile 里 ...