林德熙 - 微软最具价值专家和 .NET 基金会成员
分类 Roslyn
相信有很多伙伴热衷于编写 IDE 应用,在 dotnet 系下,通过 Roslyn 友好的 API 和强大的能力,实现一个代码智能提示是非常简单的事情。本文将和大家简单介绍一下如何使用 Roslyn 实现简单的代码智能提示补全功能
在写项目文件的时候,需要根据不同的条件定义或执行不同的代码,有一些比较常使用的判断,本文收藏起来,方便大家抄代码
本文告诉大家如何使用 Roslyn 分析代码。
本文告诉大家如何使用 Target 进行修改编译时的文件
在日常的开发中,如果需要发布多个库,多个库之间的版权和作者等信息都是相同的。如果需要每次更改信息都打开项目进行编辑,这个效率是很低的。本文提供一个方式,通过安装一个 nuget 包就可以自动填写信息。
咱造了一个轮子,咱可以非常方便将这个轮子库作为 NuGet 发布出去,造福其他开发者,或者毒害其他开发者。为什么说是毒害呢?因为有时候这个库存在坑,此时使用这个库的开发者就受到了伤害。为了安抚脆弱的开发者们,咱可以提高一下开发者们的调试效率,例如让开发者们可以调试到库里面的源代码 本文来告诉大家如何在项目文件里面添加上 EmbedAllSources 属性,将自己的代码嵌入到 PDB 符号文件里面,让开发者们在调试的时候,可以看到库的源代码
我找了很久没有发现 SolutionDir 这个定义,所以只能通过一个不通用的方法找到
默认的 PackageReference 可以实现传递依赖,传递依赖的含义是是假定 B 项目安装了 A 库,而 C 项目依赖 B 项目,那么 C 项目将会自然拿到 A 库的 DLL 引用。但默认的 NuGet 包的构建指导文件 targets 命令是不会在传递执行的,也就是如上的 C 项目将不会执行 B 项目安装的 A 库里面的 target 内容 有一些项目需要拷贝自定义文件,例如拷贝图片或者一些 Native 的 DLL 等资源。如 WPF 框架需要拷贝 PenIME 等资源。如果只是在最底层的项目安装了库,那为了让可执行文件项目也输出库的资源,就需要在可执行项目上也安装库。以上的方法的不足在于安装复杂,也许会忘记安装 本文告诉大家一个解决方法是通过在制作库的时候,加上 BuildTransitive 文件夹,在此文件夹内添加构建指导文件,此时这个构建指导文件 targets 文件里面的命令将会在传递中执行,也就是说只需要在底层的项目安装即可,不需要在可执行项目上也安装库
本文告诉大家如何在 Rosyln 编译一个文件,获得这个文件的类的命名空间
在使用新的项目格式,可以使用 Target 添加项目,但是有一些项目需要在合适的时候添加,如果添加早了,那么会让用户看到这些文件,如果添加的时间是在引用编译之后,那么文件将无法进行编译。
本文告诉大家如何在 MSBuild 里使用 Copy 复制文件
本文告诉大家如何在项目文件通过不同的条件使用不同的方法运行
本来我想说的是基于引用 msbuild 程序集来自己做一个编译器,但是想想好像本文做的,和造编译器没啥关系,咱自己调用 msbuild 的 API 而已。本文来告诉大家如何引用 msbuild 程序集,如何在自己的应用程序里面嵌入 msbuild 的构建代码,实现 dotnet build 的效果
定义在 ItemGroup 里面的各个引用文件的 Item 可带上自定义的 Metadata 内容,这部分内容需要转换到 AdditionalFiles 的 Metadata 上才能被分析器所获取
本文告诉大家如何在使用 IIncrementalGenerator 进行增量的 Source Generator 生成代码时,读取项目里的项目文件属性,从而实现为项目定制的逻辑。或者是读取 NuGet 包里面的一些配置,从而方便实现逻辑
本文告诉大家如果在 Nuget 引用源代码的方式引用源代码,在 VisualStudio 的智能提示和 Resharper 的智能提示都能找到对应的类,但是在 VisualStudio 编译或使用命令行 msbuild 编译时提示找不到类
我有一个强大的功能,这个功能就是在 Linux 下使用 GDI 转换 EMF 格式图片为 png 图片,但是有一些有趣的图片会让转换的进程炸掉。因此我就想让转换服务放在独立的进程,通过进程间调用,也就是命令行调用传入参数的方式,让另一个进程转换图片。而此时就会遇到一个问题,如何让这个进程也被构建,然后输出到输出路径
使用 SDK Style 格式的 csproj 十分简化,但是实际上的构建过程需要用到超级多的逻辑,那么如何知道在 msbuild 所使用的构建过程有哪些,定义了那些属性。有那些 target 文件参与了这个项目构建 本文告诉大家一个方法,可以输出某个项目在 msbuild 中的完全使用到的 targets 和属性等
在 SDK 格式的项目文件可以通过简单代码引用某个文件夹里面指定后缀的文件作为项目文件
本文告诉大家如何做源代码包,源代码包的意思是安装的包不是安装dll的方式,而是使用源代码的方式。也就是最后是编译包的源代码而不是添加dll,这个方式是解决想要把项目分小,功能分细,但是不希望项目有很多的 dll,因为如果项目有很多 dll 会让软件打开的时间比较长
在使用 sdk 格式的项目文件支持快速进行打包,但使用这个方式打包的时候将默认只带程序集输出文件,而没有带依赖的文件。本文告诉大家如何在打包的时候加上需要放在包里面的文件
本文来告诉大家如何用 Roslyn 管理配置,在开一个新的项目的时候经常需要添加公司,版权等,但是这些信息不想每次都添加于是我就想用 Nuget 管理所有配置,安装一个 nuget 就自动配置
我和小伙伴说只要你安装我的 NuGet 库无论你怎么做,都会调用我的 Main 函数,默认的主函数不会调用
本文告诉大家 Directory.Build.props 是什么有什么优点?如何使用 Directory.Build.props 文件定义编译
As you know, the WriteLinesToFile will separate the item by semicolons. How can we use WriteLinesToFile to write the semicolons to file?
我有一个很大的项目,这个项目里面包含了很多小的底层库。有一天我发现了某个底层库可能有小伙伴挖了一个坑,我期望调试这个底层库,但是我一点都不想编译整个大项目,因为底层库被太多的项目应用,一点点修改都需要编译很久。本文提供一个简单的方法让大家可以通过修改项目文件,让 VisualStudio 可以急速调试底层库,每次更改底层库只需要重新编译底层库就可以
在一些大项目需要很多独立的仓库来做,每个仓库之间都会有很多相同的配置,本文告诉大家如何通过 Directory.Build.props 管理多个项目配置
本文告诉大家经常使用的 NameSyntax 拿到值的 ToString 和 ToFullString 方法的区别
本文告诉大家在使用 Roslyn 分析代码时,使用的 Span 和 FullSpan 有什么区别
本文告诉大家如何在使用 IIncrementalGenerator 进行增量的 Source Generator 生成代码时,如何获取到当前正在分析的程序集所引用的所有的程序集,以及引用的程序集里面的所有类型
本文告诉大家如何在使用 IIncrementalGenerator 进行增量的 Source Generator 生成代码时,如何判断两个程序集之间是否存在 InternalsVisibleTo 关系
相信有很多伙伴都很喜欢自己造编程语言,在有现代的很多工具链的帮助下,实现一门编程语言,似乎已不是一件十分困难的事情。我利用 SourceGenerator 源代码生成技术实现了一个简易的中文编程语言,核心原理是将中文编程语言翻译为 C# 语言,从而完成后续的所有对接,完成了最简单的构建和运行。本文将告诉大家这个有趣的方式是如何实现
在带界面的 dotnet core 程序运行的时候就会出现一个控制台窗口,本文告诉大家使用最简单方法去隐藏控制台窗口。
在加上热重载时,源代码生成 Source Generator 的默认行为会让 Visual Studio 有些为难,其原因是热重载会变更代码,变更代码触发代码生成器更新代码,代码生成器更新的代码说不定又会有某些逗比逻辑再次触发热重载。于是就会发现在某些复杂的项目下,开启热重载之后,在编辑并继续界面将会等非常久,甚至再也无法继续。为了解决这个问题,大聪明设计了 Incremental Generators 机制,此 Incremental Generators 机制和 Source Generator 不冲突,被设计用来解决热重载的源代码生成性能问题,本文将告诉大家此新的 API 的入门级使用
最快的代码是什么代码?不运行的代码才是最快的代码
本文来告诉大家 msbuild Roslyn 的行为,本文非新手友好
随着源代码生成的越来越多的应用,自然也遇到了越来越多开发上的坑,例如源代码的缩进是一个绕不过去的问题。如果源代码生成是人类可见的代码,我期望生成的代码最好是比较符合人类编写代码的规范。为了能让人类在阅读机器生成的代码的时候,不会想着拿刀砍那个编写代码生成代码的开发者,最好,或者说至少代码也应该有个缩进和换行吧。本文将安利大家通过 IndentedTextWriter 这个辅助类,用来辅助生成带缩进的内容
本文将告诉大家如何在 IIncrementalGenerator 增量 Source Generator 生成代码里面,在 Roslyn 分析器里面判断两个程序集是否存在引用关系
本文将告诉大家如何在分析器里面解析代码里面对于 ValueTuple 的定义,包括如何获取 ValueTuple 里面的 Item 的类型和命名
本文将告诉大家如何在分析器里面获取到项目的默认命名空间
在开始编写 dotnet 的 Roslyn 分析器项目时,会被 VisualStudio 通过 RS1036 要求在项目文件配置上 EnforceExtendedAnalyzerRules 属性,本文将和大家介绍 EnforceExtendedAnalyzerRules 属性的作用
本文告诉大家如何在使用 IIncrementalGenerator 进行增量的 Source Generator 生成代码时,如何从语法分析过程,将获取的语法 Token 转换到语义分析上,比如获取类型完全限定名。一个使用的例子是在拿到一个 Token 表示某个类型时,本文将演示通过语义分析获取到拿到的 Token 的 Type 类型的 FullName 带命名空间的完全限定名
我期望在每次构建完成之后,创建一个文件,在这个文件里面写入是什么时间构建的。这个需求实现非常简单,只需要使用 Target 在构建完成,使用 WriteLinesToFile 方法写入时间到输出文件即可
阅读本文,你可以了解如何编写开发和调试 XAML 构建为 Baml 和 g.cs 文件的过程和工具。本文也适合想要了解 WPF 的 XAML 构建过程的开发者阅读,本文提供了可以断点调试 WPF 的 XAML 构建过程的方法和代码
本文来告诉大家一个黑科技,通过 .suo 文件读取 VisualStudio 的启动项目。在 sln 项目里面,都会生成对应的 suo 文件,这个文件是 OLE 格式的文件,文件的格式没有公开,本文的方法适合用在 VisualStudio 2019 上,对于其他版本的 VisualStudio 也许会不适合
在写 msbuild 预编译或编译调度逻辑时,如何知道当前执行的编译器使用的是上古版本的 msbuild 还是用了 dotnet core 内核的 Roslyn 编译器?本文解决的问题是我期望在 Windows 系统使用 .NET Framework 版本的工具,而在非 Windows 系统上,使用 dotnet core 版本的工具。原因是 .NET Framework 在开发者设备上都会有,用起来简单。而 dotnet core 提供了跨平台,可以在其他平台上使用
本文告诉大家如何在 MSBuild 里使用 MakeDir 创建文件夹
在旧版本的 csproj 格式也就是 Franken-proj 格式,可以使用 SolutionDir 拿到当前sln文件所在的文件夹,但是在 SDK Style 格式的项目文件,是拿不到这个属性的,本文告诉大家如何做到兼容之前的逻辑
在写 msbuild 的预编译逻辑,如果想要拿到项目安装的 NuGet 库和版本,可以通过获取 PackageReference 的方法获取
默认的 NuGet 包支持在 releaseNotes 中添加更改日志,用户可以通过更改日志了解各个版本更新的内容。在 SDK Style 格式的 csproj 文件,可以读取本地的文本文件的内容作为 NuGet 包的改动日志
本文告诉大家如何在打出的 NuGet 包含代码的注释,这样安装了 NuGet 的小伙伴就可以在 VS 上看到对应的方法和类的注释
默认在 SDK Style 的 csproj 文件将会引用所有的 .cs 文件到 Compile 项,如果是 WPF 项目还会添加 xaml 的引用。如果想要自己手动设置,让一些项不默认引用,需要添加属性 EnableDefaultCompileItems 告诉 msbuild 不要默认引用
在 csproj 文件或在 NuGet 的 Targets 文件中可以通过 Target 调用 ZipDirectory 任务用来制作压缩包,在构建的时候,可以用这个方法将某个输出文件夹等内容压缩输出
在使用 csproj 格式,如果需要给不同的平台设置 PlatformTarget 对应平台的值,需要写比较多的代码,本文告诉大家一个简便的方法
在写预编译框架,因为安装项目会基于多个平台,也就是对应的 Target 会执行多次,而我需要的只是执行一次就可以
在使用 msbuild 定义编译时运行的逻辑,可以使用 Exists 判断文件是否存在
本文告诉大家如何编写在编译过程修改打包文件
在开发的时候,小伙伴会使用右击解决方案,点击清理解决方案。在这个按钮点击的背后 msbuild 做了什么?为什么很多时候的清理之后还存在一堆文件?如何让自己想的 Target 也支持清理
在写 msbuild 脚本的时候,或修改项目文件的时候,将会使用到很多的微软提供的 Task 命令。在需要复杂的编译的时候,可以通过自己定义一个任务用来定义编译
默认无论是在 VisualStudio 还是在 dotnet 命令行都会忽略项目文件或安装库里面的消息输出,而吕水小伙伴给了一个馊主意将所有需要输出给用户的消息换为警告,因为默认是会输出警告,于是消息就可以输出了。然后某个小伙伴就过来打我,因为他一编译整个项目原本是没有警告的,现在有很多警告。于是我就在找是否有方法可以做到让消息的内容默认输出
虽然已经通过很多篇博客告诉大家如何通过 Directory.Build.props 文件修改编译的方法,但是本文还是提供一个新的思路
只需要在项目文件夹,或者磁盘的文件夹,如 E:\
放下本文提供的 Directory.Build.props 文件,整个文件夹内的控制台项目就会输出 林德熙是逗比 想要知道是怎么做的,请看下面
在写 Roslyn 的时候,经常需要辅助编译的工具,而这些工具需要传入一些参数,在项目很大的时候,会发现自己传入的参数比微软限制控制台可以传入的参数大很多,这时就无法传入了参数。 本文告诉大家如何使用 WriteLinesToFile 先把参数写入文件,通过文件的方式传输参数