取消

如何在控制台程序中监听 Windows 前台窗口的变化

前一段时间总会时不时发现当前正在打字的窗口突然失去了焦点,于是很希望有个工具能实时监听前台窗口的变化,并实时输出出来。 本文会介绍两类知识,一类是如何在 .NET/C# 程序中方便地调用 Win32 API,另一类是在控制台程序中开启 Windows 消息循环。 思路 获取当前前台窗口的本质 API 调用是 GetForegroundWindow。在拿到前台窗口的句柄后,进...

.NET/C# 程序如何在控制台/终端中以字符表格的形式输出数据

在一篇在控制台窗口中监听前台窗口的博客中,我在控制台里以表格的形式输出了每一个前台窗口的信息。在控制台里编写一个字符表格其实并不难,毕竟 ASCII 中就已经提供了制表符。不过要在合适的位置输出合适的制表符,要写一些打杂式的代码了;另外,如果还要考虑表格列的宽度自适应,再考虑中英文在控制台中的对齐,还要考虑文字超出单元格时是裁剪/省略/换行。当把所有这些麻烦加到一起之后,写一个这样的辅助类来...

在 Windows 上如何在启动程序时单独为这个程序指定环境变量,而不需要编写任何代码或脚本

有些程序没有内置提供代理的功能,但遵循环境变量中设置的代理。如果我们能有办法仅为这个特定的程序设置环境变量,那么我们就可以在不开启全局代理的情况下单独为这样的程序开启代理。 设置环境变量开启代理 比如,Unity Hub 就是这样的一个程序。为了让它开启代理,我们可以在命令行中用这样的三句命令启动它: > cd "C:\Program Files\Unity Hub" &...

如何正确调教 Visual Studio 自带的拼写检查功能

Visual Studio 2022 (17.6 Preview 2) 带来了拼写检查功能,此功能一出大家纷纷吐槽各种问题。不过团队中确实时不时会出现单词拼写错误的情况,所以有时又觉得非常需要它。 如果你打算在 Visual Studio 中好好使用这个自带的功能,那么可以阅读本文。对它有更多的了解之后,也许可以逐渐趋利避害。 开启拼写检查功能 目前,拼写检查器功能仍然是预览功...

WPF 像素着色器进阶:使用 HLSL 编写一个高性能的实时变化的 HSL/HSV/HSB 调色盘

要在代码里画一个 HSL/HSV/HSB 调色盘非常容易,不过如果这个调色盘需要实时变化,那么频繁绘制需要在 CPU 上大量创建或者修改位图,性能不太好。本文将使用 HLSL 来完成这一任务。 HLSL 入门 如果你对 WPF 使用像素着色器还不太了解,那么可以阅读入门文章: WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着...

WPF 像素着色器入门:使用 Shazzam Shader Editor 编写 HLSL 像素着色器代码

HLSL,High Level Shader Language,高级着色器语言,是 Direct3D 着色器模型所必须的语言。WPF 支持 Direct3D 9,也支持使用 HLSL 来编写着色器。你可以使用任何一款编辑器来编写 HLSL,但 Shazzam Shader Editor 则是专门为 WPF 实现像素着色器而设计的一款编辑器,使用它来编写像素着色器,可以省去像素着色器接入到 W...

Windows 10 自带那么多图标,去哪里找呢?

无意间发现我的 D 盘根目录中大部分的文件夹都是系统专用文件夹,有自己的独特图标,偶有一两个开发用的文件夹是默认图标。于是想把它们改成独特样式,而且是 Windows 10 那些新图标样式! 这是我的文件夹,我希望把最上面几个文件夹的图标改成下面那些风格。 大家都知道在文件夹上右键,选择 属性 → 自定义 → 更改图标,这里可以选择很多图标,但用了很多年看腻了,Windows 1...

如何更精准地设置 C# / .NET Core 项目的输出路径?(包括添加和删除各种前后缀)

我们都知道可以通过在 Visual Studio 中设置输出路径(OutputPath)来更改项目输出文件所在的位置。对于 .NET Core 所使用的 Sdk 风格的 csproj 格式来说,你可能会发现实际生成路径中带了 netcoreapp3.0 或者 net472 这样的子文件夹。 然而有时我们并不允许生成这样的子文件夹。本文将介绍可能影响实际输出路径的各种设置。 项目和...

如何利用 Win32 API 设置两个窗口的所有者(Owner)关系

设置两个窗口的父子关系非常简单,只需要调用 SetParent 函数即可。然而设置两个窗口的所有者(Owner)关系却没有一个简单直观的 API。那么本文介绍一下如何设置两个窗口的 Owner 关系。 设置所有者(Owner) 由于方法非常简单,所以我直接贴出 MainWindow 中的完整代码: public partial class MainWindow : Window...

WPF 的 Dispatcher 为什么要创建一个隐藏窗口?

在深入了解 WPF Dispatcher 的工作原理(Invoke/InvokeAsync 部分)中,我提到 Dispatcher 在构造函数中创建了一个隐藏窗口专门用来接收消息,以处理通过 Invoke 系列方法调用的那些操作。然而 C 不满足于只看到这个结论,他更期望知道为什么 WPF 一定要创建这个隐藏的窗口。其实对这个问题我也不知道答案,但在和他深入的探讨以及不断寻找资料的过程中,我...

Directory.GetFiles 中传入搜索字符串(Search Pattern)的神奇规则

众所周知,文件名的匹配规则里同配符 ? 代表单个字符,通配符 * 代表多个字符。然而,具体到 Directory.GetFiles(string path, string searchPattern) 方法调用时,却又有一些大家不一定知道的细节。不信?我出一道题大家试试! 一道测试题 假设在调用 Directory.GetFiles(string path, string sea...

CS8350:不允许使用“Foo(ref x, ref y)”的这种参数组合,因为它可能会在其声明范围之外公开由参数 x 引用的变量

标题所述的是一个 .NET/C# 程序的编译错误。这个编译错误是 C#7.2 时就引入的,但更新到 Visual Studio 2022(17.4) 后,有更多的情况会被判定为发生了此错误。 本文会解释这个错误的原因和解决办法。 新引入的 CS8350 编译错误 以下这段代码,在 Visual Studio 2022(17.4)版本中会出现编译错误 CS8350,但在低版本的 ...

使用 AutoMapper 自动映射模型时,处理不同模型属性缺失的问题

使用 AutoMapper 可以很方便地在不同的模型之间进行转换而减少编写太多的转换代码。不过,如果各个模型之间存在一些差异的话(比如多出或缺少一些属性),简单的配置便不太行。本文帮助你解决这个问题。 关于 AutoMapper 的系列文章: 使用 AutoMapper 自动在多个数据模型间进行转换 使用 AutoMapper 自动映射模型时,处理不同模型属性缺失的问题 ...

使用 AutoMapper 自动在多个数据模型间进行转换

访问数据库、IPC 通信、业务模型、视图模型……对于同一个业务的同一种数据,经常会使用多种数据模型工作在不同的代码模块中。这时它们之间的互相转换便是大量的重复代码了。 使用 AutoMapper 便可以很方便地在不同的模型之间进行转换而减少编写太多的转换代码(如果这一处的代码对性能不太敏感的话)。 关于 AutoMapper 的系列文章: 使用 AutoMapper 自动在多...

解决 WPF 分组的 ItemsControl 内部控件无法被 UI 自动化识别的问题

如果你试图给 WPF 的 ItemsControl 加入自动化识别,或者支持无障碍使用,会发现 ItemsControl 内的元素如果进行了分组,则只能识别到组而不能识别到元素本身。如果你正试图解决这个问题,那么本文正好能给你答案。 现象 现在,我们在 ItemsControl 的内部放几个按钮并进行分组。用自动化软件去捕获它,会发现整个 ItemsControl 会被视为一个控...

如何让 WPF 程序更好地适配 UI 自动化

Windows 中很早就内置了 UI 自动化机制(UIAutomation 从 Windows XP SP3 就开始提供了),WPF 第一个版本开始也提供了 UI 自动化的支持。所以按道理说如果你使用了 WPF,那么你的 UI 做准备好了随时可被自动化的准备。 虽说 WPF 支持不错,但我还是有几点需要说明一下: 这里我说的是“UI 自动化”,而不是“UI 自动化测试”;前者比...

最简单的代码,让 WPF 支持响应式布局

响应式布局在各种现代的 UI 框架中不是什么新鲜的概念,基本都是内置支持。然而在古老的 WPF 框架中却并没有原生支持,后来虽然通过 Blend 自带的 Interactions 库实现了响应式布局,但生成的代码量太大了,而且需要引入额外的库。 如果只是希望临时局部地方使用响应式布局,那么其实可以直接使用 WPF 内置的绑定机制来完成响应式布局。本文介绍如何使用。 思路是在控件尺寸发...

MSBuild/Roslyn 和 NuGet 的 100 个坑

MSBuild 不愧是强大的编译器,它提供的扩展机制让你几乎可以编译任何类型的文件或项目;Roslyn 是全新编写的一套编译器,不过它保留了 MSBuild 的大部分机制;NuGet 是 .NET 生态系统中的包管理机制,被原生集成在新的 Microsoft.NET.Sdk 中。 不过,他们的坑还是挺多的;本文就是他们 100 个坑的集合。 系列博客 这是兄弟篇中的一篇,关于 ...

git subtree 不断增加的推送时间,解不玩的冲突!这篇文章应该能救你

原生 git 对于公共组件那种类型的子仓库的支持并不怎么好,就是那种某个子文件夹是一个另外的 git 仓库,并被多个 git 父仓库使用的形式。实际使用的感受甚至是“糟糕透了”。 这种并不友好的子仓库支持可能与 git 的设计理念有关,不过,git 的开发者始终在打补丁以稍微优化这样的体验。 不断增加的推送时间 如果你曾经在大仓库试过 git subtree push,你一定为...

git fetch 失败,因为 unable to resolve reference 'refs/remotes/origin/xxx': reference broken

我在使用 git fetch 命令的时候,发现竟然会失败,提示错误 error: cannot lock ref 'refs/remotes/origin/xxx': unable to resolve reference 'refs/remotes/origin/xxx': reference broken。 本文介绍如何修复这样的错误,并探索此错误产生的原因。 错误 在使用...

使用 Roslyn 分析代码注释,给 TODO 类型的注释添加负责人、截止日期和 issue 链接跟踪

如果某天改了一点代码但是没有完成,我们可能会在注释里面加上 // TODO。如果某个版本为了控制影响范围临时使用不太合适的方法解了 Bug,我们可能也会在注释里面加上 // TODO。但是,对于团队项目来说,一个人写的 TODO 可能过了一段时间就淹没在大量的 TODO 堆里面了。如果能够强制要求所有的 TODO 被跟踪,那么代码里面就比较容易能够控制住 TODO 的影响了。 本文将基于 ...

基于 Roslyn 同时为 Visual Studio 插件和 NuGet 包开发 .NET/C# 源代码分析器 Analyzer 和修改器 CodeFixProvider

Roslyn 是 .NET 平台下十分强大的编译器,其提供的 API 也非常丰富好用。本文将基于 Roslyn 开发一个 C# 代码分析器,你不止可以将分析器作为 Visual Studio 代码分析和重构插件发布,还可以作为 NuGet 包发布。不管哪一种,都可以让我们编写的 C# 代码分析器工作起来并真正起到代码建议和重构的作用。 本文将教大家如何从零开始开发一个基于 Roslyn...

Roslyn 入门:使用 Roslyn 静态分析现有项目中的代码(语法分析)

Roslyn 是微软为 C# 设计的一套分析器,它具有很强的扩展性。以至于我们只需要编写很少量的代码便能够分析我们的项目文件。 作为 Roslyn 入门篇文章,你将可以通过本文学习如何开始编写一个 Roslyn 扩展项目,如何开始分析一个解决方案(.sln)中项目(.csproj)的代码文件(.cs)。 本文是 Roslyn 入门系列之一: Roslyn 入门:使用 Visu...

WPF 窗口在 Visual Studio 调试的时候会被一个莫名其妙的调试层覆盖住

同样的程序,在使用 Visual Studio 调试的时候和直接运行的时候相比,总会有一些细微之处是不同的。大多数时候这些不同可以忽略,但是一旦这些不同是我们产品需求的一部分的时候,你可能就会发现调试和非调试状态下的行为不同却找不到原因,非常抓狂! 本文记录我遇到的一个 WPF 窗口调试的案例。看完后大家至少知道 Visual Studio 调试时的一个小坑,更进一步则可以在出现奇妙问题的...

使用 ImageMagick 轻松制作带有多种尺寸的 ico 图标文件

ico 图标格式是一种包含多种尺寸位图的容器格式,Windows 用这种格式来作为图标是为了能让文件图标在各种不同显示尺寸下都能看起来清晰可辨。可是,相当多的平面设计软件都没有内嵌 ico 格式的支持(尤其是 macOS 版的),导致设计师很难直接输出 ico 格式的图标。另外,有些自称能 png 转 ico 格式的图片转换器虽然能生成 ico 格式,但这种 ico 格式内只包含一种位图尺寸...

在多个可执行程序(exe)之间共享同一个私有部署的 .NET 运行时

从 .NET Core 3 开始,.NET 应用就支持独立部署自己的 .NET 运行时。可以不受系统全局安装的 .NET 运行时影响,特别适合国内这种爱优化精简系统的情况……鬼知道哪天就被优化精简了一个什么重要 .NET 运行时组件呢!然而,如果你的项目会生成多个 exe 程序,那么他们每个独立发布时,互相之间的运行时根本不互通。即便编译时使用完全相同的 .NET 框架(例如都设为 net6...

如何检测当前操作系统是否支持运行 .NET Core 3 / .NET 5 / .NET 6 应用?

虽然微软官方声称 .NET Core 3 / .NET 5 / .NET 6 应用支持在 Windows 7 及以上运行,但你不应该轻信。因为微软还在某个隐秘的角落里说明还应安装一枚 KB2533623 补丁。 直接判断补丁肯定是不靠谱的,因为还有其他几枚补丁(KB3063858、KB4457144)包含了这枚补丁。所以有没有什么靠谱写的判断方法呢?本文就来说说。 Windows...

如何让 .NET 程序脱离系统安装的 .NET 运行时独立运行?除了 Self-Contained 之外还有更好方法!谈 dotnetCampus.AppHost 的工作原理

从 .NET Core 3 开始,.NET 应用就支持独立部署自己的 .NET 运行时。可以不受系统全局安装的 .NET 运行时影响,特别适合国内这种爱优化精简系统的情况……鬼知道哪天就被优化精简了一个什么重要 .NET 运行时组件呢!然而,如果你的项目会生成多个 exe 程序,那么他们每个独立发布时,互相之间的运行时根本不互通。即便编译时使用完全相同的 .NET 框架(例如都设为 net6...

如何编译、修改和调试 dotnet runtime 仓库中的 apphost nethost comhost ijwhost

.NET 以 MIT 协议开源,于是任何人都可以尝试对其进行一丢丢的修改以实现一些原本很难实现的功能,例如在多个可执行程序(exe)之间共享同一个私有部署的 .NET 运行时。在这个例子中,我们修改了 AppHost 添加了一个可以定制 .NET 运行时路径的功能,这就需要我们能编译、修改和调试 dotnet/runtime 仓库里的 apphost 部分。 本文将以 dotnetCamp...

修改 .NET 运行时、框架和库,从编译 dotnet runtime 仓库开始

.NET 以 MIT 协议开源,于是任何人都可以尝试对其进行一丢丢的修改以实现一些原本很难实现的功能,例如在多个可执行程序(exe)之间共享同一个私有部署的 .NET 运行时。然而,对其的修改得能够编译生成期望的文件才行。本文介绍一下如何编译 dotnet/runtime 仓库,日常使用非常简单,所以如果只是轻微修改的话,本文大概就够了。 首先记得先把仓库拉下来: dotnet...