msbuild
文章平均质量分 94
walter lv
这个作者很懒,什么都没留下…
展开
-
在 Visual Studio 的解决方案资源管理器中隐藏一些文件
项目文件中有一些属性几乎是专门为 IDE 而准备的,不过考虑到 .NET 生态的开发者多数都使用 Visual Studio,所以基本上也只有 Visual Studio 对这些特性支持的最全面。(才不会透漏这些属性其实本就是为 Visual Studio 而准备的呢。)本文将介绍如何在 Visual Studio 的解决方案资源管理器中隐藏一些文件。本文内容原生支持原生不支持变通解决活学活...原创 2020-01-28 17:47:02 · 3555 阅读 · 0 评论 -
解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程
在 csproj 中,Project 中的 Sdk 属性是 MSBuild 15.0 开始支持的,也就是 Visual Studio 2017 开始支持。有了 Sdk 属性的存在,MSBuild 编译过程能够扩展得非常强大,而不止是过去 Import 的一个 props 和 targets 文件。本文将介绍 Microsoft.NET.Sdk 的源码,以及利用源码中的一些线索来完成官方文档中没有...原创 2020-01-28 17:45:00 · 1094 阅读 · 0 评论 -
将 .NET Core 项目打一个最简单的 NuGet 源码包,安装此包就像直接把源码放进项目一样
NuGet 原本就提供了生成源码包的功能。不过,NuGet 原生的源码包仅用于调试时自带调试信息和调试源码。本文将以最简单的方式制作一个源码引用包。安装 NuGet 包后,不会生成任何程序集引用,而是相当于将源码直接放入被安装的程序集中一样。本文内容准备工作将源码加入 NuGet 包安装 NuGet 包时引入源码准备工作我们需要一个可以用来打 NuGet 包的 .NET Core 项目,...原创 2020-01-28 17:36:05 · 653 阅读 · 1 评论 -
如何在 MSBuild Target(Exec)中报告编译错误和编译警告
我曾经写过一篇文章 如何创建一个基于命令行工具的跨平台的 NuGet 工具包,通过编写一个控制台程序来参与编译过程。但是,相比于 基于 Task 的方式,可控制的因素还是太少了。有没有什么办法能够让控制台程序也能与 MSBuild Target 之间发生更多的信息交换呢?比如报告编译错误和编译警告?答案是有的,通过格式化控制台输出。本文内容编译错误和编译警告更复杂的错误和警告控制阻止编译错误...原创 2020-01-28 17:33:48 · 392 阅读 · 0 评论 -
如何编写基于 Microsoft.NET.Sdk 的跨平台的 MSBuild Target(附各种自带的 Task)
我之前写过一篇 理解 C# 项目 csproj 文件格式的本质和编译流程,其中,Target 节点就是负责编译流程的最关键的节点。但因为篇幅限制,那篇文章不便详说。于是,我在本文说说 Target 节点。本文内容Target 的节点结构Target 执行的时机和先后顺序Microsoft.NET.Sdk 为我们提供的现成可用的 Task使用自己写的 Task差量编译Target 的节点结构...原创 2020-01-28 17:18:33 · 494 阅读 · 0 评论 -
在 MSBuild 编译过程中操作文件和文件夹(检查存在/创建文件夹/读写文件/移动文件/复制文件/删除文件夹)
本文整理 MSBuild 在编译过程中对文件和文件夹处理的各种自带的编译任务(Task)。本文内容`Exists` 检查文件存在`MakeDir` 创建文件夹`Move` 移动文件`Copy` 复制文件`Delete` 删除文件`ReadLinesFromFile` 读取文件`WriteLinesToFile` 写入文件`RemoveDir` 删除文件夹Exists 检查文件存在使用 Ex...原创 2019-12-30 08:45:39 · 2497 阅读 · 0 评论 -
如何在 MSBuild 中正确使用 % 来引用每一个项(Item)中的元数据
MSBuild 中写在 <ItemGroup /> 中的每一项是一个 Item,Item 除了可以使用 Include/Update/Remove 来增删之外,还可以定义其他的元数据(Metadata)。使用 % 可以引用 Item 的元数据,本文将介绍如何正确使用 % 来引用每一个项中的元数据。本文内容定义 Item 的元数据引用元数据使用元数据关于项元数据的其他信息定义 I...原创 2019-12-30 08:42:20 · 318 阅读 · 0 评论 -
使用 MSBuild Target 复制文件的时候如何保持文件夹结构不变
使用 MSBuild 中的 Copy 这个编译目标可以在 .NET 项目编译期间复制一些文件。不过使用默认的参数复制的时候文件夹结构会丢失,所有的文件会保留在同一级文件夹下。那么如何在复制文件的时候保持文件夹结构与原文件夹结构一样呢?本文内容CopyRecursiveDirCopy下面是一个典型的使用 MSBuild 在编译期间复制文件的一个编译目标。<Target Name="...原创 2019-12-30 08:40:06 · 816 阅读 · 0 评论 -
通过 mklink 收集本地文件系统的所有 NuGet 包输出目录来快速调试公共组件代码
我们做的公共库可能通过 nuget.org 发布,也可能是自己搭建 NuGet 服务器。但是,如果某个包正在开发中,需要快速验证其是否解决掉一些诡异的 bug 的话,除了单元测试这种间接的测试方法,还可以在本地安装未发布的 NuGet 包的方法来快速调试。本文介绍如何本地打包发布 NuGet 包,然后通过 mklink 收集所有的本地包达到快速调试的目的。本文内容将本地文件夹作为 NuGet...原创 2019-10-19 09:02:20 · 316 阅读 · 0 评论 -
制作通过 NuGet 分发的源代码包时,如果目标项目是 WPF 则会出现一些问题(探索篇,含解决方案)
在使用 NuGet 包来分发源代码时,如果目标项目是 WPF 项目,那么会有一大堆的问题。本文将这些问题列举出来并进行分析。本文内容源代码包基础代码:最小的例子用于打源代码包的项目 Walterlv.SourceYard.Demo用于验证源代码包的项目 Walterlv.GettingStarted.SourceYard.Sample编译不可思议的错误普通控制台项目WPF 项目修复错误找出原...原创 2019-08-30 14:35:41 · 664 阅读 · 0 评论 -
WPF 程序的编译过程
基于 Sdk 的项目进行编译的时候,会使用 Sdk 中附带的 props 文件和 targets 文件对项目进行编译。Microsoft.NET.Sdk.WindowsDesktop 的 Sdk 包含 WPF 项目的编译过程。而本文介绍 WPF 项目的编译过程,包含 WPF 额外为编译过程添加的那些扩展编译目标,以及这些扩展的编译目标如何一步步完成 WPF 项目的过程。本文内容提前准备Tar...原创 2019-08-30 14:31:31 · 1832 阅读 · 1 评论 -
MSBuild 在编写编译任务的时候判断当前是否在 Visual Studio 中编译
我们这里说的编译任务是 MSBuild 的 Target。虽然只有少部分,但确实有一些情况需要判断是否在 Visual Studio 中编译的时候才需要执行的编译任务,典型的如某些仅为设计器准备的代码。本文需要理解的前置知识是:解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程 - walterlv而使用 Visual Studio 编译的时候,会自...原创 2019-07-27 20:43:21 · 577 阅读 · 0 评论 -
在编译期间使用 Roslyn/MSBuild 自带的方法/函数判断、计算和修改属性
充分利用 MSBuild 自带的方法,可以在编译期间完成大多数常见的属性转换,而不再需要自己专门写库来完成。本文介绍如何使用 MSBuild 自带的方法,并列举 MSBuild 中各种自带的方法。本文内容如何在编译期间使用 MSBuild 自带的方法MSBuild 自带的方法数学运算EnsureTrailingSlashGetDirectoryNameOfFileAbove & Ge...原创 2019-07-27 20:10:26 · 656 阅读 · 0 评论 -
Roslyn/MSBuild 在编译期间从当前文件开始查找父级文件夹,直到找到包含特定文件的文件夹
大家在进行各种开发的时候,往往都不是写一个单纯项目就完了的,通常都会有一个解决方案,里面包含了多个项目甚至是大量的项目。我们经常会考虑输出一些文件或者处理一些文件,例如主项目的输出目录一般会选在仓库的根目录,文档文件夹一般会选在仓库的根目录。然而,我们希望输出到这些目录或者读取这些目录的项目往往在很深的代码文件夹中。如果直接通过 ..\..\.. 来返回仓库根目录非常不安全,你会数不过来的。...原创 2019-07-27 20:09:12 · 602 阅读 · 0 评论 -
Roslyn/MSBuild 在编译期间处理路径中的斜杠与反斜杠
本文介绍如何在项目文件 csproj,或者 MSBuild 的其他文件(props、targets)中处理路径中的斜杠与反斜杠。本文内容路径中的斜杠与反斜杠判断路径末尾是否有斜杠或反斜杠确保路径末尾有斜杠或反斜杠确保路径末尾没有斜杠或反斜杠路径中的斜杠与反斜杠我们都知道文件路径的层级之间使用斜杠(/)或者反斜杠(\)来分隔,具体使用哪一个取决于操作系统。本文不打算对具体使用哪一种特别说明,...原创 2019-06-29 10:03:42 · 824 阅读 · 0 评论 -
在 Roslyn/MSBuild 中进行基本的数学运算
在任何一种编程语言中,做基本的数学运算都是非常容易的事情。不过,不知道 .NET 项目的项目文件 csproj 文件中进行数学运算就不像一般的编程语言那样直观了,毕竟这不是一门语言,而只是一种项目文件格式而已。本文介绍如何在 Roslyn/MSBuild 的项目文件中使用基本的数学运算。本文内容Roslyn/MSBuild 中的数学运算加减乘除模不要试图在 MSBuild 中使用传统的数学运...原创 2019-06-29 10:02:46 · 332 阅读 · 0 评论 -
为 NuGet 指定检测的 MSBuild 路径或版本,解决 MSBuild auto-detection: using msbuild version 自动查找路径不合适的问题
使用 nuget restore 命令还原项目的 NuGet 包的时候,NuGet 会尝试自动检测计算机上已经安装的 MSBuild。不过,如果你同时安装了 Visual Studio 2017 和 Visual Studio 2019,那么 NuGet 有可能找到错误版本的 MSBuild。本文介绍如何解决自动查找版本错误的问题。本文内容问题使用命令行参数解决修改环境变量解决问题当我们...原创 2019-09-27 09:25:37 · 1959 阅读 · 0 评论 -
MSBuild 中的特殊字符($ @ % 等):含义、用法以及转义
在 MSBuild 中有一些特殊字符,如 $ @ % ' 等,本文介绍他们的含义,如何使用他们,以及你真的需要这些字符的时候如何编写他们。本文内容特殊字符含义和用法`$``@``%``'``;``?` 和 `*`转义特殊字符MSBuild 中有这些特殊字符:$@%';?*含义和用法$引用一个属性或者环境变量。<Project> <ItemGr...原创 2019-06-29 09:45:41 · 1659 阅读 · 0 评论 -
从零开始制作 NuGet 源代码包(全面支持 .NET Core / .NET Framework / WPF 项目)
系。跟着本教程你也可以制作出来一个源代码包,只不过可能遇到了问题的时候不容易调试和解决。制作一个源代码包接下来,我们将从零开始制作一个源代码包。我们接下来的将创建一个完整的解决方案,这个解决方案包括:一个将打包成源代码包的项目一个调试专用的项目(可选)一个测试源代码包的项目(可选)第一步:创建一个 .NET 项目像其他 NuGet 包的引用项目一样,我们需要创建一个空的项目。不...原创 2019-08-30 14:47:24 · 834 阅读 · 0 评论 -
.NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
在为 .NET 项目扩展 MSBuild 编译而编写编译目标(Target)时,我们会遇到用于扩展编译目标用的属性 BeforeTargets AfterTargets 和 DependsOnTargets。这三个应该分别在什么情况下用呢?本文将介绍其用法。BeforeTargets / AfterTargetsBeforeTargets 和 AfterTargets 是用来扩展编译用的。...原创 2019-08-30 15:04:54 · 1105 阅读 · 0 评论 -
编写 Target 检测 MSBuild / dotnet build 此次编译是否是差量编译
MSBuild 或 Roslyn 编译项目时均支持差量编译,毕竟为了性能。我在 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译 一文中介绍了如何使一个 Target 支持差量编译。在那篇文章中我说到差量编译会导致 Target 不执行;也就是说,如果一个 Target 对后续的编译会产生影响,那么一定不能设置为差量编译。不过,真的会写...原创 2018-11-28 15:47:24 · 490 阅读 · 0 评论 -
Visual Studio 2019 中使用 .NET Core 预览版 SDK 的全局配置文件在哪里?
本文介绍在使用 Visual Studio 2019 或者命令行执行 MSBuild dotnet build 命令时,决定是否使用 .NET Core SDK 预览版的全局配置文件。指定是否使用 .NET Core 预览版 SDK 的全局配置文件在:%LocalAppData%\Microsoft\VisualStudio\16.0_xxxxxxxx\sdk.txt其中 %Local...原创 2019-09-27 09:36:25 · 1282 阅读 · 0 评论 -
如何在 Visual Studio 2019 中设置使用 .NET Core SDK 的预览版(全局生效)
.NET Core 3 相比于 .NET Core 2 是一个大更新。也正因为如此,即便它长时间处于预览版尚未发布的状态,大家也一直在使用。Visual Studio 2019 中提供了使用 .NET Core SDK 预览版的开关。但几个更新的版本其开关的位置不同,本文将介绍在各个版本中的位置,方便你找到然后设置。本文内容Visual Studio 2019 (16.3 及以上)Visua...原创 2019-09-27 09:33:13 · 5994 阅读 · 0 评论 -
找出 .NET Core SDK 是否使用预览版的全局配置文件在哪里(探索篇)
你是否好奇 Visual Studio 2019 中的 .NET Core SDK 预览版开关是全局生效的,那个全局的配置在哪里呢?本文将和你一起探索找到这个全局的配置文件。本文内容使用 Process Monitor 探索下载 Process Monitor打开 Process Monitor设置过滤规则捕获 devenv.exe捕获 MSBuild.exe验证结论其他反编译探索使用 P...原创 2019-09-27 09:31:55 · 568 阅读 · 0 评论 -
nuget.exe 还原解决方案 NuGet 包的时候出现错误:调用的目标发生了异常。Error parsing the nested project section in solution file
我这里使用 Visual Studio 2019 能好好编译的一个项目,发现在另一个小伙伴那里却编译不通过,是在 NuGet 还原那里报告了错误:调用的目标发生了异常。Error parsing the nested project section in solution file.本文介绍如何解决这样的问题。原因此问题的原因可能有多种:解决方案里面 Project 和 EndP...原创 2019-09-27 09:29:18 · 1308 阅读 · 0 评论 -
两种方法设置 .NET/C# 项目的编译顺序,而不影响项目之间的引用
当 A 项目引用 B 项目,那么使用 Visual Studio 或者 MSBuild 编译 A 项目之前就会确保 B 项目已经编译完毕。通常我们指定这种引用是因为 A 项目确实在运行期间需要 B 项目生成的程序集。但是,现在 B 项目可能仅仅只是一个工具项目,或者说 A 项目编译之后的程序集并不需要 B,仅仅只是将 B 打到一个包中,那么我们其实需要的仅仅是 B 项目先编译而已。本文介绍如何...原创 2019-09-27 09:27:27 · 3301 阅读 · 0 评论 -
.NET/MSBuild 中的发布路径在哪里呢?如何在扩展编译的时候修改发布路径中的文件呢?
在扩展 MSBuild 编译的时候,我们一般的处理的路径都是临时路径或者输出路径,那么发布路径在哪里呢?我曾经在下面这一篇博客中说到可以通过阅读 Microsoft.NET.Sdk 的源码来探索我们想得知的扩展编译的答案:解读 Microsoft.NET.Sdk 的源码,你能定制各种奇怪而富有创意的编译过程 - walterlv于是,我们可以搜索 "Publish" 这样的关键字找到我...原创 2019-08-30 15:10:11 · 1760 阅读 · 0 评论 -
在项目文件 / MSBuild / NuGet 包中编写扩展编译的时候,正确使用 props 文件和 targets 文件
.NET 扩展编译用的文件有 .props 文件和 .targets 文件。不给我选择还好,给了我选择之后我应该使用哪个文件来编写扩展编译的代码呢?如果你不了解 .props 文件或者 .targets 文件,可以阅读下面的博客:理解 C# 项目 csproj 文件格式的本质和编译流程 - walterlv具体的例子有下面这些博客。不过大概阅读一下就好,这只是 .props 和 .ta...原创 2019-08-30 15:05:56 · 1154 阅读 · 0 评论 -
在项目文件 csproj 中或者 MSBuild 的 Target 中使用 % 引用集合中每一项的属性
在编写项目文件或者 MSBuild Target 文件的时候,我们经常会使用 <Foo Include="Identity" /> 来定义集合中的一项。在定义的同时,我们也会额外指定一些属性。然而这些属性如何拿到并且使用呢?本文将介绍使用方法。将下面的代码放到你项目文件的末尾,最后一个 </Project> 的前面,可以在编译的时候看到两个新的警告。<Targ...原创 2019-06-29 09:41:43 · 822 阅读 · 0 评论 -
C# 可空引用类型 NullableReferenceTypes 更强制的约束:将警告改为错误 WarningsAsErrors
程序员不看警告!于是 C# 8.0 带来的可空引用类型由于默认以警告的形式出现,所以实际上约束力非常弱。本文将把 C# 8.0 的可空引用类型警告提升为错误,以提高约束力。本文内容启用可空引用类型项目属性WarningsAsErrors启用可空引用类型你需要先在你的项目中启用可空引用类型的支持,才能修改警告到错误:C# 8.0 如何在项目中开启可空引用类型的支持 - 吕毅项目属...原创 2019-05-28 14:17:21 · 898 阅读 · 0 评论 -
让 MSBuild Target 支持 Clean
我们有时候会使用解决方案的清理(Clean)功能来解决一些项目编译过程中非常诡异的问题。这通常是一些 Target 生成了一些错误的中间文件,但又不知道到底是哪里错了。我们自己编写 Target 的时候,也可能会遇到这样的问题,所以让我们自己的 Target 也能支持 Clean 可以在遇到诡异问题的时候,用户可以自己通过清理解决方案来消除错误。以下代码来自于 SourceFusion/Pa...原创 2019-02-01 09:25:53 · 568 阅读 · 0 评论 -
在 Target 中获取项目引用的所有依赖(dll/NuGet/Project)的路径
在项目编译成 dll 之前,如何分析项目的所有依赖呢?可以在在项目的 Target 中去收集项目的依赖。本文将说明如何在 Target 中收集项目依赖的所有 dll 的文件路径。本文内容编写 Target以上 Target 的输出Reference 的输出ReferencePath 的输出解读原因编写 Target<Target Name="WalterlvDemoTarget" ...原创 2019-02-01 09:25:16 · 1472 阅读 · 0 评论 -
通过重写预定义的 Target 来扩展 MSBuild / Visual Studio 的编译过程
MSBuild 的编译过程提供了一些可以被重写的 Target,通过重写这些 Target 可以扩展 MSBuild 的编译过程。本文内容重写预定义的 Target`BeforeCompile`, `AfterCompile``BeforeBuild`, `AfterBuild``BeforeRebuild`, `AfterRebuild``BeforeClean`, `AfterClean`...原创 2019-02-01 09:20:59 · 912 阅读 · 0 评论 -
在 Roslyn 分析语法树时添加条件编译符号的支持
我们在代码中会写 #if DEBUG 或者 [Conditional("DEBUG")] 来使用已经定义好的条件编译符号。而定义条件编译符号可以在代码中使用 #define WALTERLV 来实现,也可以通过在项目属性中设置条件编译符号(Conditional Compilation Symbols)来实现。然而如果我们没有做任何特殊处理,那么使用 Roslyn 分析使用了条件编译符号的源码时...原创 2019-01-01 11:01:04 · 716 阅读 · 0 评论 -
.NET/C# 项目如何优雅地设置条件编译符号?
条件编译符号指的是 Conditional Compilation Symbols。你可以在 Visual Studio 的项目属性中设置,也可以直接在项目文件中写入 DefineConstants 属性。不过对于不同种类的项目,我建议使用不同的设置方法。本文将介绍如何设置条件编译符。对于新旧格式的差别或者迁移,可以查看我的其他博客:理解 C# 项目 csproj 文件格式的本质和编译流...原创 2019-01-01 11:00:22 · 3907 阅读 · 1 评论 -
Visual Studio 2017 以前的旧格式的 csproj Import 进来的 targets 文件有时不能正确计算属性(PropertyGroup)和集合(ItemGroup)
我在之前的博客中有教大家如何编写 NuGet 工具包,其中就有编写 .targets 文件。我在实际的使用中,发现 Visual Studio 2017 带来的含 Sdk 的新 csproj 格式基本上没有多少坑;然而旧的 csproj 文件却总是不能完美的运行,总是出错。关键是,不是每台电脑都出错,不是每个时机都出错。本文将讲一些坑。本文内容本文的前置知识问题原因解决办法衍生知识本文的...原创 2018-12-23 15:16:54 · 1328 阅读 · 0 评论 -
.NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
.NET/C# 程序从 Main 函数开始执行,基本上各种书籍资料都是这么写的。不过,我们可以写多个 Main 函数,然后在项目文件中设置应该选择哪一个 Main 函数。你可能会觉得这样没有什么用,不过如果你的应用程序在不同的编译条件下有不同的启动代码,或者你需要持续去大范围修改启动代码,那么做一个 Main 函数的选择器是一个不错的选择。本为内容在哪里选择 Main?我们准备一个 WPF ...原创 2018-10-28 11:41:24 · 3193 阅读 · 0 评论 -
预编译框架,开发高性能应用 - 课程 - 微软技术暨生态大会 2018
微软技术暨生态大会(Tech Summit),2018 年在上海世博中心召开。这是最后一次的 Tech Summit 了;明年开始,中国大陆地区就要和其他国家和地区一样,进行全球 Ignite Tour 了。我也有幸成为分会场讲师团队的一员,课程是《预编译框架 - 开发高性能应用》。内容就是我博客中与 MSBuild / Roslyn / dotnet / NuGet 相关的内容;我们将利用这些...原创 2018-10-15 08:45:47 · 855 阅读 · 0 评论 -
都是用 DllImport?有没有考虑过自己写一个 extern 方法?
你做 .NET 开发的时候,一定用过 DllImport 这个特性吧,这货是用于 P/Invoke (Platform Invoke, 平台调用) 的。这种 DllImport 标记的方法都带有一个 extern 关键字。那么有没有可能我们自己写一个自己的 extern 方法呢?答案是可以的。本文就写一个这样的例子。DllImport日常我们的平台调用代码是这样的:...原创 2018-09-09 10:10:07 · 1358 阅读 · 0 评论 -
(2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
每次使用 Visual Studio 的模板创建一个 UWP 程序,我们会在项目中发现大量的项目文件、配置、应用启动流程代码和界面代码。然而这些文件在 UWP 程序中到底是如何工作起来的?我从零开始创建了一个 UWP 程序,用于探索这些文件的用途,了解 UWP 程序的启动流程。本文分为两个部分:从零开始创建一个 UWP 项目并完成部署从零开始编写一个 UWP 应用程序和窗口...原创 2018-07-27 07:19:11 · 3307 阅读 · 0 评论