lindexi

林德熙 - Windows 10 App Developer

林德熙

dotnet 6 使用 File.Exists 判断管道是否存在将让下次连接失败

我尝试在 dotnet 6 使用 File.Exists 判断管道是否存在,如果管道存在再进行连接。然而这个逻辑将会接下来的 NamedPipeClientStream 调用 Connect 连接失败

WPF 切换主题使用 luna 复古版本

本文告诉大家如何在 WPF 里面使用 luna 等复古主题

WPF 应用启动过程同时启动多个 UI 线程且访问 ContentPresenter 可能让多个 UI 线程互等

在应用启动过程里,除了主 UI 线程之外,如果还多启动了新的 UI 线程,且此新的 UI 线程碰到 ContentPresenter 类型,那么将可能存在让新的 UI 线程和主 UI 线程互等。这是多线程安全问题,不是很好复现,即使采用 demo 的代码,也需要几千次运行才能在某些配置比较差的机器上遇到新的 UI 线程和主 UI 线程互等,应用启动失败。本文来告诉大家复现的步骤,以及原因,和解决方法

dotnet 谨慎在静态构造函数里使用锁

在 dotnet 的最佳实践里面,不推荐在静态构造函数里面包含复杂的逻辑,其中也就包含了本文聊的和多线程相关的锁的使用。最佳做法是尽量不要在静态构造函数里面碰到任何和锁以及多线程安全相关的逻辑。本文来告诉大家,在静态构造函数里面使用锁将带来的问题以及原因

开源项目

这是我收藏的开源项目

用 SetWindowPos 方法设置一个停止响应的窗口将卡调用方

我使用 User32 的 SetWindowPos 方法去设置一个跨进程的窗口,这个窗口是停止响应的,将让调用的 SetWindowPos 方法卡住,不继续执行逻辑。通过堆栈分析是卡在 NtUserSetWindowPos 方法上,调用 SetWindowPos 方法不返回

支持 dotnet 6 的 dnSpy 神器版本

官方的 dnSpy 在 2021 时,由于某些吃瓜的原因 wtfsck 将 dnSpy 给 Archived 掉,在大佬被哄好之前,预计是不再更新。最新官方版本对 dotnet 6 的支持较弱,对于很多 dotnet 6 应用都无法成功调试,附加调试上去将会让应用卡住。好在 dnSpy 是开源的,也刚好 lsj 大佬改得动,于是改了一个支持 dotnet 6 的版本

记将一个大型客户端应用项目迁移到 dotnet 6 的经验和决策

在经过了两年的准备,以及迁移了几个应用项目积累了让我有信心的经验之后,我最近在开始将团队里面最大的一个项目,从 .NET Framework 4.5 迁移到 .NET 6 上。这是一个从 2016 时开始开发,最多有 50 多位开发者参与,代码的 MR 数量过万,而且整个团队没有一个人能说清楚项目里面的所有功能。此项目引用了团队内部的大量的基础库,有很多基础库长年不活跃。此应用项目当前也有近千万的用户量,迁移的过程也需要准备很多补救方法。如此复杂的一个项目,自然需要用到很多黑科技才能完成到 .NET 6 的落地。本文将告诉大家这个过程里,我踩到的坑,以及学到的知识,和为什么会如此做

dotnet 使用 ConfigureAwait.Fody 库设置默认的 await 同步上下文切换配置

在 dotnet 里面,使用 await 进行异步逻辑,默认是会尝试切换回调用 await 的线程同步上下文。这个机制对于大多数的上层应用来说都是符合逻辑且方便的逻辑,例如对于带 UI 线程的 WPF 或 WinForms 等应用,基础开发的执行逻辑基本都是在 UI 线程上,此时进入一次 await 再出来,期望如果是进入 await 之前是在 UI 线程,那么执行 await 完成之后,退出的代码也能在 UI 线程执行,正好这就是 dotnet 的默认行为。但是对于库开发者来说,情况就反过来的,库的开发者大部分时候更期望默认不要切换回调用方的线程,采用 Fody 的 ConfigureAwait.Fody 库,可以控制此默认的行为。本文将告诉大家如何使用 ConfigureAwait.Fody 库

dotnet 6 在 Win7 系统证书链错误导致 HttpWebRequest 内存泄露

本文记录我将应用迁移到 dotnet 6 之后,在 Win7 系统上,因为使用 HttpWebRequest 访问一个本地服务,此本地服务开启 https 且证书链在此 Win7 系统上错误,导致应用内存泄露问题。本文记录此问题的原因以及调查过程

dotnet OpenXML SDK 形状几何 Geometry 的计算公式含义

本文来告诉大家,在 OpenXML 里面的 Geometry 的如 gdLst 和 ahLst 和 pathLst 等里面参数的公式的参数含义

dotnet 5 破坏性改动 WPF 和 WinForms 的 OutputType 输出类型重定向为 WinExe 类型

官方团队为了防逗比,默认将 OutputType 输出类型重定向为 WinExe 类型,这样能解决很多新手遇到的 WPF 项目显示出黑框控制台界面问题。而对于一些老司机来说,这个特点反而有点迷,特别是在尝试打开控制台调试的时候

开源实战

本文记录我参与的开源项目

dotnet 6 通过 DOTNET_ROOT 让调起的应用的进程拿到共享的运行时文件夹

我的应用是独立发布的,在用户的设备上不需要额外去安装 .NET 运行时。但是我的应用有一个需求是下载另一个应用作为插件,由本应用调起插件进程。本文告诉大家如何解决调用插件的进程时,赋值给插件进程运行时的文件夹路径,解决环境依赖

Total Commander 使用 mklink 建立文件夹链接 将 C 盘文件迁移到其他盘

在安装完成了 100000000 个软件之后,我 1T 的 C 盘的空间终于不足了,由于安装了大量的特别挑的不专业的软件,强行放在其他的盘将水土不服。于是在老师傅的指导下,我采用了 mklink 神奇命令行,通过 mklink 可以实现将实际的文件放在其他的盘,然后建立链接到原先的地方,在应用上层基本感知不到文件的实际存储地方已经被更换。也就是物理上的文件存放是可以在另一个磁盘上,但软件以为文件还在原来的地方 这是一个不错的方法,我需要处理的文件夹还稍微有点多,就想着写一点小工具,在 Total Commander 里面,辅助我快速完成工作

dotnet 一些代码审查套路

本文记录一些代码审查套路,在看到小伙伴写出某些代码的时候可以告诉他这样写有锅

Roslyn 在项目文件使用条件判断

本文告诉大家如何在项目文件通过不同的条件使用不同的方法运行

C# 高级面试题

很少会有人可以答对,如果你遇到一个来面试的人实在嚣张,就可以用本文的题去打击 本文内容就看着玩,请不要在严肃的面试中问题这样的题目

dotnet 为大型应用接入 ApplicationStartupManager 启动流程框架

对于大型的应用软件,特别是客户端应用软件,应用启动过程中,需要执行大量的逻辑,包括各个模块的初始化和注册等等逻辑。大型应用软件的启动过程都是非常复杂的,而客户端应用软件是对应用的启动性能有所要求的,不同于服务端的应用软件。设想,用户双击了桌面图标,然而等待几分钟,应用才启动完毕,那用户下一步会不会就是点击卸载了。为了权衡大型应用软件在启动过程,既需要执行复杂的启动逻辑,又需要关注启动性能,为此过程造一个框架是一个完全合理的事情。我所在的团队为启动过程造的库,就是本文将要和大家介绍我所在团队开源的 dotnetCampus.ApplicationStartupManager 启动流程框架的库

WPF 播放 gif

本文告诉大家如何在 WPF 播放 Gif 图片,提供了几个方法进行播放,包括比较性能。

C# 获取 PC 序列号

在 C++ 需要使用 GetSystemFirmwareTable 的方法来获得 PC 的序列号,需要写的代码很多,但是在 C# 可以使用 WMI 来拿到序列号

WPF 多线程下跨线程处理 ObservableCollection 数据

本文告诉大家几个不同的方法在 WPF 里,使用多线程修改或创建 ObservableCollection 列表的数据

dotnet 6 使用 Obfuscar 进行代码混淆

本文来安利大家 Obfuscar 这个好用的基于 MIT 协议开源的混淆工具。这是一个非常老牌的混淆工具,从 2014 年就对外分发,如今已有累计 495.5K 的 nuget 下载量。而且此工具也在不断持续迭代更新,完全支持 dotnet 6 版本,对 WPF 和 WinForms 等等的支持也是非常好,支持多个不同混淆方式和等级的配置,支持混淆之后生成符号文件。本文将来告诉大家如何使用此混淆工具,以及此工具能达成的效果和此工具混淆的原理

WPF 开发

本文:我遇到的WPF的坑

dotnet 5 的 bin 文件夹下的 ref 文件夹是做什么用的

本文来和大家聊聊在 dotnet 5 和 dotnet 6 或更高版本的 dotnet 构建完成,在 bin 文件夹下,输出的 ref 文件夹。在此文件夹里面,将会包含项目程序集同名的 dll 文件,但是此 dll 文件的大小却很小,那这个文件夹是用来做什么的

dotnet 6 使用 string.Create 提升字符串创建和拼接性能

本文告诉大家,在 dotnet 6 或更高版本的 dotnet 里,如何使用 string.Create 提升字符串创建和拼接的性能,减少拼接字符串时,需要额外申请的内存,从而减少内存回收压力

dotnet 读 WPF 源代码笔记 为什么加上 BooleanBoxes 类

在 WPF 框架,为什么需要定义一个 BooleanBoxes 类。为什么在 D3DImage 的 Callback 方法里面,传入的是 object 对象,却能被转换为布尔。本文将告诉大家为什么需要这样设计

XAML 给资源起个好名字 用 StaticResource 起一个别名

本文来和大家聊一下关于 XAML 资源的定义的事情,和开发技术关系不大,更多的是开发的思路

WPF 通过 GifBitmapDecoder 调用 WIC 解析 Gif 和进行动画播放的简单方法

本文告诉大家如何在 WPF 里,通过 GifBitmapDecoder 调用 WIC 层来解析 GIF 图片,然后采用动画的方式进行播放

WPF 全屏窗口将让 Chrome 97 视频停止播放

无论是使用 WPF 全屏窗口,还是高性能全屏透明窗口,都会在 Chrome 97 以及使用 chromium 对应版本内核的应用的视频停止播放。这是 chromium 的一个优化,因为 chromium 认为,如果有全屏窗口盖在上面,自然此时停止播放视频可以节省资源。然而 chromium 却没有考虑到,有很多会议的应用,虽然是全屏的,但也是透明的,于是此时停止播放视频将是非预期的

WPF 已知问题 Popup 失焦后导致 ListBox 无法用 MouseWheel 滚动问题和解决方法

本文记录在 Popup 失焦后导致 ListBox 无法用 MouseWheel 滚动问题

WPF 已知问题 Popup 吃掉 PreviewMouseDown 事件

在 WPF 中,使用 Popup 也许会看到 PreviewMouseDown 事件被吃掉

WPF 从最底层源代码了解 AllowsTransparency 性能差的原因

当前的 WPF 的源代码完全开放,本文将从最底层的 WPF 代码告诉大家为什么设置了 AllowsTransparency 之后性能会变差,以及 WPF 透明的原理

dotnet 新 SDK Style 项目格式如何使用 InternalsVisibleToAttribute 功能

如果一个项目想要让其他某个指定的项目可以使用到 internal 的类或成员,可以通过标记 InternalsVisibleToAttribute 的方式实现