.NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets? 2019-07-01 08:43 在为 .NET 项目扩展 MSBuild 编译而编写编译目标(Target)时,我们会遇到用于扩展编译目标用的属性 BeforeTargets AfterTargets 和 DependsOnTargets。 这三个应该分别在什么情况下用呢?本文将介绍其用法。
使用 Visual Studio 编译时,让错误一开始发生时就停止编译(以便及早排查编译错误节省时间) 2019-06-30 05:36 对于稍微大一点的 .NET 解决方案来说,编译时间通常都会长一些。如果项目结构和差量编译优化的好,可能编译完也就 5~30 秒,但如果没有优化好,那么出现 1~3 分钟都是可能的。 如果能够在编译出错的第一时间停止编译,那么我们能够更快地去找编译错误的原因,也能从更少的编译错误列表中找到出错的关键原因。
C#/.NET 移动或重命名一个文件夹(如果存在,则合并而不是出现异常报错) 2019-06-29 04:57 .NET 提供了一个简单的 API 来移动一个文件夹 Directory.Move(string sourceDirName, string destDirName)。不过如果你稍微尝试一下这个 API 就会发现其实相当不实用。
如何追踪 WPF 程序中当前获得键盘焦点的元素并显示出来 2019-06-29 01:07 我们有很多的调试工具可以帮助我们查看 WPF 窗口中当前获得键盘焦点的元素。本文介绍监控当前键盘焦点元素的方法,并且提供一个不需要任何调试工具的自己绘制键盘焦点元素的方法。
如何监视 WPF 中的所有窗口,在所有窗口中订阅事件或者附加 UI 2019-06-28 00:38 由于 WPF 路由事件(主要是隧道和冒泡)的存在,我们很容易能够通过只监听窗口中的某些事件使得整个窗口中所有控件发生的事件都被监听到。然而,如果我们希望监听的是整个应用程序中所有的事件呢?路由事件的路由可并不会跨越窗口边界呀? 本文将介绍我编写的应用程序窗口监视器,来监听整个应用程序中所有窗口中的路由事件。这样的方法可以用来无时无刻监视 WPF 程序的各种状态。
.NET/C# 如何获取当前进程的 CPU 和内存占用?如何获取全局 CPU 和内存占用? 2019-06-27 23:48 都知道可以在任务管理器中查看进程的 CPU 和内存占用,那么如何通过 .NET 编写代码的方式来获取到 CPU 和内存占用呢? .NET 中提供了 PerformanceCounter 类型,可以用来监视系统中大量的性能问题。
从 git 的历史记录中彻底删除文件或文件夹 2019-06-23 08:43 如果你对外开源的代码中出现了敏感信息(例如你将私钥上传到了仓库中),你可能需要考虑将这个文件从 git 的历史记录中完全删除掉。 本文介绍如何从 git 的历史记录中彻底删除文件或文件夹。
.NET 中让 Task 支持带超时的异步等待 2019-06-21 01:17 Task 自带有很多等待任务完成的方法,有的是实例方法,有的是静态方法。有的阻塞,有的不阻塞。不过带超时的方法只有一个,但它是阻塞的。 本文将介绍一个非阻塞的带超时的等待方法。
.NET 使用 ILMerge 合并多个程序集,避免引入额外的依赖 2019-06-17 13:34 我们有多种工具可以将程序集合并成为一个。打包成一个程序集可以避免分发程序的时候带上一堆依赖而出问题。 ILMerge 可以用来将多个程序集合并成一个程序集。本文介绍使用 ILMerge 工具和其 NuGet 工具包来合并程序集和其依赖。
.NET 使用 ILRepack 合并多个程序集(替代 ILMerge),避免引入额外的依赖 2019-06-17 13:30 我们有多种工具可以将程序集合并成为一个。比如 ILMerge、Mono.Merge。前者不可定制、运行缓慢、消耗资源(不过好消息是现在开源了);后者已被弃用、不受支持且基于旧版本的 Mono.Cecil。 而本文介绍用来替代它们的 ILRepack,使用 ILRepack 来合并程序集。
Windows 10 解决无法完整下载安装语言包(日语输入法无法下载使用) 2019-06-16 12:53 最近我想在我的 Windows 10 上安装一个新的语言包,在 “设置” -> “时间和语言” -> “语言” 中,添加了新的语言之后,语言进入了下载状态。但是没过一小会儿,下载进度条就结束了,提示语言已经下载安装完成。但实际上只能作为显示使用,(日语)输入法却不能使用。 我找了很多的资料试图解决这个问题,但发现竟然没有任何一种现有方法可以解决我的问题(这可能是日语输入法特有的问题吧)。最终解决后,我将网上搜集到的方法以及我实际解决所使用的方法都收录进来,方便大家后续解决问题。
.NET 的程序集加载上下文 2019-06-13 05:49 我们编写的 .NET 应用程序会使用到各种各样的依赖库。我们都知道 CLR 会在一些路径下帮助我们程序找到依赖,但如果我们需要手动控制程序集加载路径的话,需要了解程序集加载上下文。 如果你不了解程序集加载上下文,你可能会发现你加载了程序集却不能使用其中的类型;或者把同一个程序集加载了两次,导致使用到两个明明是一样的类型时却抛出异常提示不是同一个类型的问题。
WPF 程序的编译过程 2019-06-11 08:05 基于 Sdk 的项目进行编译的时候,会使用 Sdk 中附带的 props 文件和 targets 文件对项目进行编译。Microsoft.NET.Sdk.WindowsDesktop 的 Sdk 包含 WPF 项目的编译过程。 而本文介绍 WPF 项目的编译过程,包含 WPF 额外为编译过程添加的那些扩展编译目标,以及这些扩展的编译目标如何一步步完成 WPF 项目的过程。
制作通过 NuGet 分发的源代码包时,如果目标项目是 WPF 则会出现一些问题(探索篇,含解决方案) 2019-06-11 07:30 在使用 NuGet 包来分发源代码时,如果目标项目是 WPF 项目,那么会有一大堆的问题。 本文将这些问题列举出来并进行分析。
MSBuild 在编写编译任务的时候判断当前是否在 Visual Studio 中编译 2019-06-04 14:23 我们这里说的编译任务是 MSBuild 的 Target。虽然只有少部分,但确实有一些情况需要判断是否在 Visual Studio 中编译的时候才需要执行的编译任务,典型的如某些仅为设计器准备的代码。
git 配置错误导致无法推送远端仓库?本文介绍各种修复方式 2019-06-04 07:31 无论你使用原生的 git 命令行,还是使用其他的 GUI 客户端来管理你的 git 仓库,都会遇到 git 远程仓库的身份认证机制。如果在某个远程仓库第一次认证的时候输入了错误的信息,那么 git 以及一部分 git GUI 客户端会记住这个错误的身份认证信息,使得以后也不能继续与远程仓库进行交互了。 本文介绍如何清除 git 的身份认证信息,以便你可以重新获得输入正确身份认证的机会。
使用 ProcessMonitor 找到进程所操作的文件的路径 2019-06-01 05:49 很多系统问题都是可以修的,不需要重装系统,但是最近我还是重装了。发现之前正在玩的一款游戏的存档没有了……因为我原有系统的数据并没有删除,所以我还是能找回原来的游戏存档的。但是,我怎么知道这款游戏将存档放在了那个路径下呢?搜索当然是好方法,不过我喜欢玩的游戏大多是冷门游戏,有些搜不到。于是我就用 Process Monitor 找到了存档所在,恢复了我的游戏进度。 本文介绍如何使用 ProcessMonitor 找出进程创建和修改的文件路径。
如何为 Win32 的打开和保存对话框编写文件过滤器(Filter) 2019-05-31 12:36 在使用 Win32 / WPF / Windows Forms 的打开或保存文件对话框的时候,多数情况下我们都会考虑编写文件过滤器。UWP 中有 FileTypeFilter 集合可以添加不同的文件种类,但 Win32 中却是一个按一定规则组合而成的字符串。 因为其包含一定的格式,所以可能写错。本文介绍如何编写 Filter。
将基于 .NET Framework 的 WPF 项目迁移到基于 .NET Core 3 2019-05-31 12:11 在 Connect(); 2018 大会上,微软发布了 .NET Core 3 Preview,以及基于 .NET Core 3 的 WPF;同时还发布了 Visual Studio 2019 预览版。你可以基于 .NET Core 3 创建 WPF 程序。不过,如果你已经有基于 .NET Framework 的 WPF 项目,那么如何快速迁移到基于 .NET Core 的版本呢? 本文将指导大家将现有基于 .NET Framework 的 WPF 项目迁移到基于 .NET Core 3 的版本。
.NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉 2019-05-28 13:31 当我们不再使用某个对象的时候,此对象会被 GC 垃圾回收掉。当然前提是你没有写出内存泄漏的代码。我们也知道如果生成了大量的字符串,会对 GC 造成很大的压力。 但是,如果在编译期间能够确定的字符串,就不会被 GC 垃圾回收掉了。
.NET/C# 避免调试器不小心提前计算本应延迟计算的值 2019-05-28 10:51 延迟计算属性的值,应该很多小伙伴都经常使用。比如在属性的 get 方法中判断是否已初始化,如果没有初始化则立即开始初始化。 但这样的写法存在一个很大的问题——如果你使用 Visual Studio 调试,当你把鼠标划到对象的实例上的时候,属性就会立刻开始进行初始化。而此时对你的代码来说可能就过早初始化了。我们不应该让调试器非预期地影响到我们程序的执行结果。 本文介绍如何避免调试器不小心提前计算本应延迟计算的值。
cmd.exe 的命令行启动参数(可用于执行命令、传参或进行环境配置) 2019-05-25 01:50 有一些程序不支持被直接启动,而要求通过命令行启动。这个时候,你就需要使用 cmd.exe 来启动这样的程序。我们都知道如何在 cmd.exe 中启动一个程序,但是当你需要自动启动这个程序的时候,你就需要知道如何通过 cmd.exe 来启动一个程序,而不是手工输入然后回车运行了。 本文就介绍 cmd.exe 的命令行启动参数。利用这些参数,你可以自动化地通过 cmd.exe 程序来完成一些原本需要通过手工执行的操作或者突破一些限制。
在 Visual Studio 中重新将高级保存功能放出来,便于强制指定文件编码格式 2019-05-23 12:25 Visual Studio 的早期版本中有一个高级保存功能,但是升级到 Visual Studio 2019 之后这个功能就不在菜单项里面了。 本文将带你把它找出来继续使用。
WPF 使用 AppBar 将窗口停靠在桌面上,让其他程序不占用此窗口的空间(附我封装的附加属性) 2019-05-23 10:53 本文介绍如何使用 Windows 的 AppBar 相关 API 实现固定停靠在桌面上的特殊窗口。
在整个 Git 仓库的历史(包括所有分支和标签)中修改提交作者的信息(姓名和邮箱) 2019-05-23 08:15 一般情况下不建议修改 git 仓库的历史。 但是现在我计划开源我的一个项目,于是自己个人使用的姓名和邮箱就需要在开源的时候改为使用我公开的姓名和邮箱。对于旧仓库,我将废弃,将来所有的精力都将在开源版本的仓库中;而对于开源版本的新仓库,由于此前没有人克隆过,所以也不会因为历史的修改产生问题。所以,我可以很放心地更改全部的 git 仓库历史。
.NET/C# 使用 ConditionalWeakTable 附加字段(CLR 版本的附加属性,也可用用来当作弱引用字典 WeakDictionary) 2019-05-23 05:17 如果你使用过 WPF/UWP 等 XAML UI 框架,那么应该了解到附加属性的概念。那么没有依赖属性支持的时候如何做附加属性的功能呢?你可能会想到弱引用。但这需要做一个弱引用字典,要写的代码还是非常麻烦的。 本文介绍 .NET 的 ConditionalWeakTable<TKey,TValue> 类型,适用于 .NET Framework 4.0 以上和全部 .NET Core 的版本。
WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 2019-05-22 11:53 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口。但是,如果直接判断是否是 Window 类型,那么在设计器中这个属性的设置就会直接出现异常。 那么有没有什么方法能够得知这是一个设计时的窗口呢?这样就不会抛出异常,而能够完美支持设计器了。
通过修改环境变量修改当前进程使用的系统 Temp 文件夹的路径 2019-05-16 12:03 Windows 系统提供了一个在 Windows 单个用户下全局的 Temp 文件夹,用于给各种不同的应用程序提供一个临时目录。但是,直到 Windows 10 推出存储感知功能之前,这个文件夹都一直只归各个应用程序自己管理,应用自己需要删除里面的文件。另外,进程多了,临时文件也会互相影响(例如个数过多、进程读写竞争等等)。 本文介绍将自己当前进程的 Temp 文件夹临时修改到应用程序自己的一个临时目录下,避免与其他程序之间的各种影响,同时也比较容易自行清理。
Markdown 如何在内联代码或者代码块中使用代码开始符号反引号(`) 2019-05-15 14:09 我们都知道如何在 Markdown 中使用反引号 ` 来包裹一段代码。无论是内联的代码还是单独的代码块,都需要使用它,只是个数的差别,比如 ` 和 ```。 那么如何能够在代码片中输入反引号(backtick)呢?