.NET 编译过程
文章平均质量分 91
深入 .NET 的编译过程,通过解读修改 csproj 文件,利用 NuGet 包的机制,通过干预编译过程使得项目具有更高的性能和更好的易用性。
walter lv
这个作者很懒,什么都没留下…
展开
-
.NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
.NET/C# 程序从 Main 函数开始执行,基本上各种书籍资料都是这么写的。不过,我们可以写多个 Main 函数,然后在项目文件中设置应该选择哪一个 Main 函数。你可能会觉得这样没有什么用,不过如果你的应用程序在不同的编译条件下有不同的启动代码,或者你需要持续去大范围修改启动代码,那么做一个 Main 函数的选择器是一个不错的选择。本为内容在哪里选择 Main?我们准备一个 WPF ...原创 2018-10-28 11:41:24 · 3193 阅读 · 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 评论 -
(1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
每次使用 Visual Studio 的模板创建一个 UWP 程序,我们会在项目中发现大量的项目文件、配置、应用启动流程代码和界面代码。然而这些文件在 UWP 程序中到底是如何工作起来的?我从零开始创建了一个 UWP 程序,用于探索这些文件的用途,了解 UWP 程序的启动流程。本文分为两个部分:从零开始创建一个 UWP 项目并完成部署从零开始编写一个 UWP 应用程序和窗口...原创 2018-07-27 07:17:16 · 3044 阅读 · 0 评论 -
如何使用 MSBuild Target(Exec)中的控制台输出
我曾经写过一篇文章 如何创建一个基于命令行工具的跨平台的 NuGet 工具包,通过编写一个控制台程序来参与编译过程。但是,相比于 基于 Task 的方式,可控制的因素还是太少了。有没有什么办法能够让控制台程序也能与 MSBuild Target 之间发生更多的信息交换呢?答案是有的,通过捕获控制台的输出!捕获控制台输出如果你喜爱阅读文档,那么答案已经不陌生了,在微软的官方文...原创 2018-06-26 20:51:11 · 702 阅读 · 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 评论 -
编写 Target 检测 MSBuild / dotnet build 此次编译是否是差量编译
MSBuild 或 Roslyn 编译项目时均支持差量编译,毕竟为了性能。我在 每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译 一文中介绍了如何使一个 Target 支持差量编译。在那篇文章中我说到差量编译会导致 Target 不执行;也就是说,如果一个 Target 对后续的编译会产生影响,那么一定不能设置为差量编译。不过,真的会写...原创 2018-11-28 15:47:24 · 490 阅读 · 0 评论 -
预编译框架,开发高性能应用 - 课程 - 微软技术暨生态大会 2018
微软技术暨生态大会(Tech Summit),2018 年在上海世博中心召开。这是最后一次的 Tech Summit 了;明年开始,中国大陆地区就要和其他国家和地区一样,进行全球 Ignite Tour 了。我也有幸成为分会场讲师团队的一员,课程是《预编译框架 - 开发高性能应用》。内容就是我博客中与 MSBuild / Roslyn / dotnet / NuGet 相关的内容;我们将利用这些...原创 2018-10-15 08:45:47 · 855 阅读 · 0 评论 -
在制作跨平台的 NuGet 工具包时,如何将工具(exe/dll)的所有依赖一并放入包中
NuGet 提供了工具类型的包支持,生成一个基于 .NET Core 的 dll 或者基于 .NET Framework 的 exe 之后,你几乎可以对项目做任何事情。但是,默认情况下,NuGet 不会将这些工具的依赖一起打包进入 NuGet 包 nupkg 文件内,这就使得功能比较复杂的跨平台 NuGet 工具包几乎是无法正常工作的。本文将介绍将这些依赖加入 NuGet 包中的方法,使得复杂...原创 2018-07-19 19:56:04 · 1172 阅读 · 0 评论 -
每次都要重新编译?太慢!让跨平台的 MSBuild/dotnet build 的 Target 支持差量编译
如果你干预到了项目的编译过程,可能就需要考虑到差量编译了。不然——当你的项目大起来的时候,就会感受到每次都重新编译时,每次重复调试的过程都要进行漫长等待时的绝望和无奈。如果你正遭遇差量编译失效,每次都要重新编译的问题,那么阅读本文应该能够帮助你解决问题。msbuild.exe 和 dotnet build 编译项目的方式是一样的,只不过前者使用完整的 .NET Framework,而后...原创 2018-05-19 08:12:30 · 1866 阅读 · 1 评论 -
理解 C# 项目 csproj 文件格式的本质和编译流程
写了这么多个 C# 项目,是否对项目文件 csproj 有一些了解呢?Visual Studio 是怎么让 csproj 中的内容正确显示出来的呢?更深入的,我能够自己扩展 csproj 的功能吗?本文将直接从 csproj 文件格式的本质来看以上这些问题。阅读本文,你将:可以通读 csproj 文件,并说出其中每一行的含义可以手工修改 csproj 文件,以实现你希望达到的高...原创 2018-05-19 07:58:23 · 6630 阅读 · 5 评论 -
项目文件中的已知 NuGet 属性(使用这些属性,创建 NuGet 包就可以不需要 nuspec 文件啦)
知道了 csproj 文件中的一些常用 NuGet 属性,创建 NuGet 包时就可以充分发挥新 Sdk 自动生成 NuGet 包的优势,不需要 nuspec 文件啦。(毕竟 nuspec 文件没有 .csproj 和 .targets 文件强大而又有扩展性。)“项目文件中的已知属性系列”分为两个部分:项目文件中的已知属性(知道了这些,就不会随便在 csproj 中写死常量啦) - ...原创 2018-05-19 07:55:25 · 2754 阅读 · 2 评论 -
使用 GitVersion 在编译或持续构建时自动使用语义版本号(Semantic Versioning)
我们在之前谈过 语义版本号(Semantic Versioning),在项目中应用语义版本号能够帮助库的开发者在发布包时表明更多的语义信息。这是趋势,从微软的博客 Versioning NuGet packages in a continuous delivery world 三部曲中可以看出,从 NuGet 4.3.0 以及 Visual Studio 2017 15.3 以上版本开始支持语义版...原创 2018-04-15 10:38:42 · 2686 阅读 · 0 评论 -
语义版本号(Semantic Versioning)
版本号格式不陌生吧,.NET 传统的版本号格式类似这样 1.5.1254.0。本文将推荐一种新的版本号格式——语义版本号,格式类似这样 1.4.6-beta。我推荐语义版本号是因为这样的版本号自包含语义,而且这样的语义能够在版本库中体现出来。传统的版本号如果你只是知道传统版本号由四个部分组成,那么建议去官方文档 Assembly Versioning 了解一下这种版本号的定义。...原创 2018-04-15 10:36:30 · 4572 阅读 · 0 评论 -
VS 编译太慢了吗?新建解决方案配置关闭一部分项目的编译
手头的解决方案真大!里面的项目个数达到了 30 个或是 50 个?然而接近一半是单元测试项目和辅助工具。再加上一些不尽如人意的项目优化,编译速度真的是无力吐槽。幸好 Visual Studio 提供了解决方案配置功能,可以让我们在编译时略过一些项目。在解决方案上右击选择“属性”,我们将打开“解决方案属性页”。在属性页种选择“配置”,则可以开始指定项目是否生成或部署。然而,我...原创 2018-04-05 17:06:36 · 5351 阅读 · 0 评论 -
使用 MSBuild 响应文件 (rsp) 来指定 dotnet build 命令行编译时的大量参数
在为开源项目 easiwin/MSTestEnhancer 进行持续集成编译时,需要在编译命令中传入较多的参数。这对于新接手此项目的人来说,成本还是高了一点儿。本文将介绍 MSBuild 响应文件 (MSBuild Response Files, *.rsp) 来优化命令行编译体验。我们在 msbuild 命令中加入 /? 参数可以看到它对响应文件的解释:> dotnet b...原创 2018-04-05 17:05:35 · 919 阅读 · 0 评论 -
命令“"xxx.exe" xxx”已退出,代码为 n。这些错误是什么意思?
命令“”xxx.exe” xxx”已退出,代码为 n。我们在 cmd 中输入常见命令的时候,如果命令输入错误或使用错误,cmd 中会提示错误原因,帮助我们定位并解决问题。然而如果相同的命令放到了 Visual Studio 的生成事件中,我们就只能得到 Visual Studio 返回的错误代码了。为了能够快速地根据错误代码大致猜测错误原因,本文整理了一部分错误代码的通用原因。我会在遇到新的错...原创 2018-03-19 19:43:05 · 3453 阅读 · 0 评论 -
生成代码,从 <T> 到 <T1, T2, Tn> —— 自动生成多个类型的泛型
当你想写一个泛型 的类型的时候,是否想过两个泛型参数、三个泛型参数、四个泛型参数或更多泛型参数的版本如何编写呢?是一个个编写?类小还好,类大了就杯具!事实上,在 Visual Studio 中生成代码的手段很多,本文采用最笨的方式生成,但效果也很明显——代码写得轻松写得爽!我们想要的效果我们现在有一个泛型的版本:public class Demo{ pu原创 2018-01-31 13:37:17 · 824 阅读 · 0 评论 -
让一个 csproj 项目指定多个开发框架
可移植类库、共享项目、.NET Standard 项目都能够帮我们完成跨多个 .NET SDK 的单一项目开发,但它们的跨 SDK 开发都有些限制。现在,我们又有新的方式能够跨多个 .NET SDK 开发了,这就是使用新的 csproj 文件格式。看看拥有多个开发框架的项目长什么样吧! ▲ 多 SDK 项目是不是很激动?新 csproj 文件在 如何组织一个同时面原创 2018-01-30 08:45:27 · 1586 阅读 · 0 评论 -
将 WPF、UWP 以及其他各种类型的旧样式的 csproj 文件迁移成新样式的 csproj 文件
写过 .NET Standard 类库或者 .NET Core 程序的你一定非常喜欢微软为他们新开发的项目文件(对于 C#,则是 csproj 文件)。这种文件非常简洁,组织一个庞大的项目也只需要聊聊二三十行;也非常易读,你可以轻易地修改其代码而不用经过过多的提前学习。当然,微软曾经尝试过用 project.json 来组织项目文件,不过只有短短的预览版阶段用过,此后就废弃了。然而组织传统 .原创 2018-01-30 08:37:44 · 831 阅读 · 0 评论 -
(C#)if (this == null)?你在逗我,this 怎么可能为 null!用 IL 编译和反编译看穿一切
if (this == null) Console.WriteLine("this is null"); 这句话一写,大家一定觉得荒谬,然而 if 内代码的执行却是可能的!本文讲介绍到底发生了什么。制造一个 this 可以为 null 的程序请看代码,这是我们的库函数:namespace Walterlv.Demo{ public class Foo ...原创 2018-03-31 08:40:31 · 1983 阅读 · 0 评论 -
从 “x is null 和 x == null” 的区别看 C# 7 模式匹配中常量和 null 的匹配
尝试过写 if (x is null)?它与 if (x == null) 相比,孰优孰劣呢?x is null 还有 x is constant 是 C# 7.0 中引入的模式匹配(Pattern Matching)中的一个小细节。阅读本文将了解 x is constant 和 x == constant 之间的差别,并给出一些代码编写建议。原创 2017-11-06 23:20:51 · 4066 阅读 · 0 评论