取消

Windows 中的 UAC 用户账户控制

阅读本文,你可以初步了解 Windows 上的 UAC 用户账户控制机制。本文不会涉及到 UAC 的底层实现原理和安全边界问题。 用户账户 在 Windows 中有多种不同的账户: SYSTEM Administrators 用户组 Administrator 管理员账户 Users 用户组 ...

Windows 下使用 runas 命令以指定的权限启动一个进程(非管理员、管理员)

在默认情况下,Windows 系统中启动一个进程会继承父进程的令牌。如果父进程是管理员权限,那么子进程就是管理员权限;如果父进程是标准用户权限,那么子进程也是标准用户权限。 我们也知道,可以使用一些方法为自己的应用程序提权。但是有没有方法可以任意指定一个权限然后运行呢?本文将介绍 Windows 下指定权限运行的做法。 runas 命令 runas 是 Windows 系统上自...

启用 Windows 审核模式(Audit Mode),以 Administrator 账户来设置电脑的开箱体验

在你刚刚安装完 Windows,在 Windows 开箱体验输入以创建你的用户账户之前,你可以按下 Ctrl + Shift + F3 来进入审核模式。 本文将介绍审核模式。 OOBE OOBE,Out-of-Box Experience,开箱体验。对于 Windows 系统来说,就是当你买下电脑回来,兴奋地打开电脑开机后第一个看到的界面。 具体来说,就是设置你的账号以及各种...

如何创建应用程序清单文件 App.Manifest,如何创建不带清单的应用程序

如果你的程序对 Windows 运行权限有要求,那么需要设置应用程序清单。本文介绍如何添加应用程序清单,并解释其中各项权限设置的实际效果。 嵌入带默认设置的清单 对于 WPF 和 Windows Forms 程序,如果你什么都不做,那么就已经嵌入了一个带有默认设置的清单。 下图可以在 Visual Studio 中的项目上右键属性插件。 新建一个自定义的清单文件 在项目...

在有 UI 线程参与的同步锁(如 AutoResetEvent)内部使用 await 可能导致死锁

AutoResetEvent、ManualResetEvent、Monitor、lock 等等这些用来做同步的类,如果在异步上下文(await)中使用,需要非常谨慎。 本文将说一个在同步上下文中非常常见的一种用法,换成异步上下文中会产生死锁的问题。 一段正常的同步上下文的代码 先看看一段非常简单的代码: private void OnLoaded(object sender,...

.NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况

一个简单的 Task 不会消耗多少时间,但如果你不合适地将 Task 转为同步等待,那么也可能很快耗尽线程池的所有资源,出现类似死锁的情况。 本文将以一个最简单的例子说明如何出现以及避免这样的问题。 耗时的 Task.Run 谁都不会认为 Task.Run(() => 1) 这个异步任务执行会消耗多少时间。 但实际上,如果你的代码写得不清真,它真的能消耗大量的时间,这种...

在编写异步方法时,使用 ConfigureAwait(false) 避免使用者死锁

我在 使用 Task.Wait()?立刻死锁(deadlock) 一文中站在类库使用者的角度看 async/await 代码的死锁问题;而本文将站在类库设计者的角度来看死锁问题。 阅读本文,我们将知道如何编写类库代码,来尽可能避免类库使用者出现那篇博客中描述的死锁问题。 可能死锁的代码 现在,我们是类库设计者的身份,我们试图编写一个 RunAsync 方法用以异步执行某些操作。...

将 async/await 异步代码转换为安全的不会死锁的同步代码(使用 PushFrame)

在 async/await 异步模型(即 TAP Task-based Asynchronous Pattern)出现以前,有大量的同步代码存在于代码库中,以至于这些代码全部迁移到 async/await 可能有些困难。这里就免不了将一部分异步代码修改为同步代码。然而传统的迁移方式存在或多或少的问题。本文将总结这些传统方法的坑,并推出一款异步转同步的新方法,解决传统方法的这些坑。 ...

使用 Task.Wait()?立刻死锁(deadlock)

最近读到一篇异步转同步的文章,发现其中没有考虑到异步转同步过程中发生的死锁问题,所以特地在本文说说异步转同步过程中的死锁问题。 文章作者 林德熙 已经修复了描述: win10 uwp 异步转同步 什么情况下会产生死锁? 调用 Task.Wait() 或者 Task.Result 立刻产生死锁的充分条件: 调用 Wait() 或 Result 的代码位于 UI 线程...

不要使用 Dispatcher.Invoke,因为它可能在你的延迟初始化 Lazy 中导致死锁

WPF 中为了 UI 的跨线程访问,提供了 Dispatcher 线程模型。其 Invoke 方法,无论在哪个线程调用,都可以让传入的方法回到 UI 线程。 然而,如果你在 Lazy 上下文中使用了 `Invoke`,那么当这个 `Lazy` 跨线程并发时,极有可能导致死锁。本文将具体说说这个例子。 一段死锁的代码 请先看一段非常简单的 WPF 代码: private Laz...

C#/.NET 如何结束掉一个进程

本文介绍如何结束掉一个进程。 结束掉特定名字的进程 ProcessInfo 中有 Kill 实例方法可以调用,也就是说如果我们能够拿到一个进程的信息,并且对这个进程拥有访问权限,那么我们就能够结束掉它。 使用 Process.GetProcessesByName(processName) 可以按照名字拿到进程信息。于是我们可以使用这个方法杀掉具有特定名称的进程。 privat...

让你的 VSCode 具备调试 C# 语言 .NET Core 程序的能力

如果你是开发个人项目,那就直接用 Visual Studio Community 版本吧,对个人免费,对小团体免费,不需要这么折腾。 如果你是 Mac / Linux 用户,不想用 Visual Studio for Mac 版;或者不想用 Visual Studio for Windows 版那么重磅的 IDE 来开发简单的 .NET Core 程序;或者你就是想像我这么折腾,那我们就开...

手工编辑 tasks.json 和 launch.json,让你的 VSCode 具备调试 .NET Core 程序的能力

如果 C# for Visual Studio Code 没有办法自动为你生成正确的 tasks.json 和 launch.json 文件,那么可以考虑阅读本文手工创建他们。 前期准备 你需要安装 .NET Core Sdk、Visual Studio Code 和 C# for Visual Studio Code,然后打开一个 .NET Core 的项目。如果你没有准备,请...

自然码的形码

使用拼音/双拼输入法,如果你的打字速度还需要继续提升,那么就不应该再不断地看着候选框打字了。使用双拼形码可以规避相当多字词的选字。 本文整理自然码的形码,然后附带一张我自己制作的自然码形码的键盘图。 输入法的选择 目前各种双拼输入法中,辅码最接近自然码形码的,是手心输入法。所以我选用了手心输入法并重新训练了词库。 这款输入法与 360 有点关系,不过很不 360。这让我有点犹...

在 Visual Studio Code 中添加自定义的代码片段

无论是那个编辑器,如果能够添加一些自定义代码片段,能够大大提升代码的输入效率。 本文介绍如何在 Visual Studio Code 中添加自定义代码片段。 Visual Studio Code 的代码片段设置 你可以在 Visual Studio Code 的菜单中找到代码片段的设置入口,在 File -> Preferences -> User Snippets...

解决 mklink 使用中的各种坑(硬链接,软链接/符号链接,目录链接)

通过 mklink 命令可以创建文件或文件夹的链接,而这种链接跟快捷方式是不一样的。然而我们还可能会遇到其使用过程中的一些坑,本文将整理这些坑并提供解决方法。 0x00 背景介绍:mklink mklink 可以像创建快捷方式一样建立文件或文件夹的链接,但不同于快捷方式的是,mklink 创建的链接绝大多数程序都不会认为那是一个链接,而是一个实实在在的文件或文件夹。 例如,为 ...

.NET 中的轻量级线程安全

对线程安全有要求的代码中,通常会使用锁(lock)。自 .NET 诞生以来就有锁,然而从 .NET Framework 4.0 开始,又诞生了 6 个轻量级的线程安全方案:SpinLock, SpinWait, CountdownEvent, SemaphoreSlim, ManualResetEventSlim, Barrier。 类型 SpinLock, SpinWait Sp...

UI 设计中的视觉无障碍设计(色盲眼中的世界以及 UI 使用体验)

我给博客改了主题色,从 这样的 改成了 这样的;然而我问小伙伴看看效果他却并没有发现改变。 红绿色盲在亚洲人中占比,男性约 5%,女性则小得多。也就是说,就算仅考虑为国内用户开发应用,这也是很大的一部分用户了。 本文将通过更加了解色盲(Color Blindness)来指导我们为更多用户提供更好的 UI 设计。 没有色盲模拟器 大多数想理解色盲眼中世界的人可能会考虑“色盲...

C#/.NET 中的契约式编程,以及 ReSharper 为我们提供的契约特性

将文档放到代码里面,文档才会及时地更新! 微软从 .NET Framework 4.0 开始,增加了 System.Diagnostics.Contracts 命名空间,用来把契约文档融入代码。然而后面一直不冷不热,Visual Studio 都没天然支持。 ReSharper 也提供了 ReSharper Annotations,在 ReSharper 插件工作的情况下能够进行...

我收集的各种公有 NuGet 源

本文收集我发现的各种公共 NuGet 源。 如何添加本文介绍的 NuGet 源? 请参见: 全局或为单独的项目添加自定义的 NuGet 源 官方 NuGet 源 官方源 https://api.nuget.org/v3/index.json 官方离线本地源 C:\Program Files (x8...

在 csproj 文件中使用系统环境变量的值(示例将 dll 生成到 AppData 目录下)

Windows 系统以及很多应用程序会考虑使用系统的环境变量来传递一些公共的参数或者配置。Windows 资源管理器使用 %var% 来使用环境变量,那么我们能否在 Visual Studio 的项目文件中使用环境变量呢? 本文介绍如何在 csproj 文件中使用环境变量。 遇到的问题 在 Windows 资源管理器中,我们可以使用 %AppData% 进入到用户的漫游路径。我...

为 WPF 程序添加 Windows 跳转列表的支持

Windows 跳转列表是自 Windows 7 时代就带来的功能,这一功能是跟随 Windows 7 的任务栏而发布的。当时应用程序要想用上这样的功能需要调用 shell 提供的一些 API。 然而在 WPF 程序中使用 Windows 跳转列表功能非常简单,在 XAML 里面就能完成。本文将介绍如何让你的 WPF 应用支持 Windows 跳转列表功能。 一个简单的跳转列表程...

Windows 上的应用程序在运行期间可以给自己改名(可以做 OTA 自我更新)

程序如何自己更新自己呢?你可能会想到启动一个新的程序或者脚本来更新自己。然而 Windows 操作系统允许一个应用程序在运行期间修改自己的名称甚至移动自己到另一个文件夹中。利用这一点,我们可以很简单直接地做程序的 OTA 自动更新。 本文将介绍示例程序运行期间改名并解释其原理。 在程序运行期间手工改名 我们写一个简单的程序。 将它运行起来,然后删除。我们会发现无法删除它。...

.NET 使用 JustAssembly 比较两个不同版本程序集的 API 变化

最近我大幅度重构了我一个库的项目结构,使之使用最新的项目文件格式(基于 Microsoft.NET.Sdk)并使用 SourceYard 源码包来打包其中的一些公共代码。不过,最终生成了一个新的 dll 之后却心有余悸,不知道我是否删除或者修改了某些 API,是否可能导致我原有库的使用者出现意料之外的兼容性问题。 另外,准备为一个产品级项目更新某个依赖库,但不知道更新此库对我们的影响有多大...

详解 .NET 反射中的 BindingFlags 以及常用的 BindingFlags 使用方式

使用 .NET 的反射 API 时,通常会要求我们传入一个 BindingFlags 参数用于指定反射查找的范围。不过如果对反射不熟的话,第一次写反射很容易写错导致找不到需要的类型成员。 本文介绍 BindingFlags 中的各个枚举标记的含义、用途,以及常用的组合使用方式。 所有的 BindingFlags 默认值 // 默认值 Default 查找 这些标记用于反...

如何使用 MyGet 这个激进的 NuGet 源体验日构建版本的 .NET Standard / .NET Core

很多库都会在 nuget.org 上发布预览版本,不过一般来说这个预览版本也是大多可用的。然而想要体验日构建版本,这个就没有了,毕竟要照顾绝大多数开发者嘛…… 本文介绍如何使用 MyGet 这个激进的 NuGet 源,介绍如何使用框架级别的库的预览版本如 .NET Standard 的预览版本。 加入 MyGet 这个 NuGet 源 添加 NuGet 源的方法在我和林德熙的博...

常用输入法快速输入自定义格式的时间和日期(搜狗/QQ/手心/微软拼音)

几个主流的输入法输入 rq 或者 sj 都可以得到预定义格式的日期或者时间。然而他们都是预定义的格式;当我们需要一些其他格式的时候该怎么做呢? 本文将介绍几个常用输入法自定义时间和日期格式的方法。 主流输入法的日期格式一般是这样的: ▲ 微软拼音 ▲ 搜狗拼音 ▲ QQ 拼音 如果自定义,可以是这样: ▲ UTC 自定义 输出效果像这样: 2018-08-26 ...

使用一句 git 命令将仓库的改动推送到所有的远端

git 支持一个本地仓库包含多个远端(remote),这对于开源社区来说是一个很重要的功能,可以实时获取到最新的开源代码且能推送到自己的仓库中提交 pull request。 有时候多个远端都是自己的,典型的就是 GitHub Pages 服务了,推送总是希望这几个远端能够始终和本地仓库保持一致。本文将介绍一个命令推送到所有远端的方法。 我的博客同时发布在 GitHub 仓库 htt...

.NET/C# 获取一个正在运行的进程的命令行参数

在自己的进程内部,我们可以通过 Main 函数传入的参数,也可以通过 Environment.GetCommandLineArgs 来获取命令行参数。 但是,可以通过什么方式来获取另一个运行着的程序的命令行参数呢? 进程内部获取传入参数的方法,可以参见我的另一篇博客:.NET 命令行参数包含应用程序路径吗?。 .NET Framework / .NET Core 框架内部是不包含获...

WPF 让普通 CLR 属性支持 XAML 绑定(非依赖属性),这样 MarkupExtension 中定义的属性也能使用绑定了

如果你写了一个 MarkupExtension 在 XAML 当中使用,你会发现你在 MarkupExtension 中定时的属性是无法使用 XAML 绑定的,因为 MarkupExtension 不是一个 DependencyObject。 本文将给出解决方案,让你能够在任意的类型中写出支持 XAML 绑定的属性;而不一定要依赖对象(DependencyObject)和依赖属性(Depe...