Matrix 精选

Matrix 是少数派的写作社区,我们主张分享真实的产品体验,有实用价值的经验与思考。我们会不定期挑选 Matrix 最优质的文章,展示来自用户的最真实的体验和观点。

文章代表作者个人观点,少数派仅对标题和排版略作修改。


Windows 平台有不少好用的命令行工具,许多有 UI 的软件也能在终端中被调用。我常常用它们来做一些轻量重复的文件处理工作。但久而久之,我开始厌烦每次输入一样的命令和参数,点击文件右键解压的操作给了我灵感,能不能将命令行工具写入右键,实现点击文件右键即可移动备份文件、压缩上传图片呢?

实现原理

注册表之于 Windows 系统,就像 ini、json 文件之于一些软件,是 Windows 平台的高级「控制面板」。注册表中 HKEY_CLASSES_ROOT (HKCR) 控制着文件和文件夹的打开方式、类型以及与之相应的鼠标右键菜单。一个典型的控制右键菜单的 HKCR 目录如下图所示:

文件目录结构

「.xxx」的项是后缀名,它的「默认」键值指向一个与键值同名的项,在这个项的 shell 目录下,就是点击该类文件会出现的一部分右键菜单。因此,只需要在某一类型文件的 shell 目录下写入自定义命令,就能改造系统右键菜单。

案例一:将安装包文件备份到特定文件夹

我有把一些可能还会用到的安装包备份到特定文件夹的习惯,可以用这个例子来说明如何定制特定类型的文件右键菜单。

所谓备份文件,说白了就是移动或者复制文件到某个文件夹,安装包不需要保留在原文件夹,所以直接移动即可。在 PowerShell 中,可以使用 mi(Move-Item) 进行移动文件操作,移动安装包到 D 盘的 exe 文件夹就是:

mi 安装包路径 D:\exe\

下面,需要找到安装包文件对应的注册表项。安装包一般是以 .exe 或者 .msi 结尾,以 exe 为例,在 HKEY_CLASSES_ROOT 下选择 .exe 这个项,记下右侧面板「默认」键的数据「exefile」,这是与之相关的文件夹名。

注册表的 .exe 指向 exefile

然后,找到 exefile 文件夹,在其中的 shell 目录下新建一个项,命名为「备份」,如果不做其他设置,这个文件夹名就是右键菜单的名字。在「备份」下新建一个项「command」,用来储存菜单对应的命令,注意大小写,注册表的键名对大小写敏感。完成后,文件夹结构应该像这样:

新建「备份」菜单

最后,点击 command,修改右侧面板中默认的数据,写入

"powershell.exe" "mi %1 D:\exe"

第一个引号中是点击菜单后打开的程序,一般需要写完整的路径,但 powershell 可以被系统直接调用(在环境变量路径中),所以只用写一个程序名。第二个引号内是参数,这里写入 powershell 要执行的命令,「%1」代表选中的文件路径。如果某个命令内部没有空格,引号也可以省略。确认无误后,保存即可生效。效果展示:

单文件
多文件

案例二:转换图片格式、压缩图片

处理图片类型文件,将它们压缩、转换格式是再常见不过的工作 了。这个案例将展示如何在注册表中使用第三方命令行工具,以及如何处理多个类型文件。

我在 一行命令,搞定常见图片、音频、视频、文本格式转换 中简要介绍了图片处理工具 Magick 的安装与使用, 要在右键中使用它,首先确保你已经正确安装了该工具。以 Magick 转换图片为 icon 图标为例,基本的命令应该是magick 图片路径 图片名.ico,不过转换之前还要处理两个问题,其一, ico 格式转换要求原图片尺寸不能太大,因此在转换前需要有选择地对图像进行缩放;其二,magick 有输入输出两个参数,「图片名」是个变量,注册表「%1」是包含了后缀的文件名,因此还需要为输出文件设定一个单独的变量,最终的命令是:

magick 图片路径 -set filename:name '%t' -resize '128x128>' 'C%[filename:name].ico'

-set 表示设定一个用作输出文件名的变量,并用%t(在 magick 中表示不带后缀的图片名)赋值,-resize '128x128>表示当图片尺寸大于 128x128 时,将原图片缩小。假设原图片文件是 256 x 256 的 sspai.png,那么处理后的图片就是 128 x 128 的 Csspai.ico。相较而言,压缩图片就简单的多,只需要用 -quality 选项即可:

magick 图片路径 -quality 50 -set filename:name '%t' 'O%[filename:name].jpg'

接下来处理注册表。因为图片格式实在太多,像案例一那样在某个类型项中修改不太现实,我们不妨让这些命令对所有文件都生效,这需要用到注册表中 HKEY_CLASSES_ROOT 下的 * 项。另外,我打算把「转换为ico」、「压缩图片」这两个命令作为「图片处理」的子菜单,方便查看和管理。参照第一个案例,首先在 * 的 shell 目录建立这样一个目录结构:

图片处理:目录

为了让多级目录生效,还需要在「图片处理」添加一个名为「SubCommands」的字符串值,告诉系统这是一个多级目录,数据留空。

多级菜单

下面在「转换为 ico」的 command 目录下写入数据:"powershell.exe" "magick %1 -set filename:name '%%t' -resize '128x128>' 'C%%[filename:name].ico'"在「压缩图片」的 command 目录下写入数据:"powershell.exe" "magick %1 -quality 50 -set filename:name '%%t' 'O%%[filename:name].jpg'"这两行命令和前面的不一样:在每一个变量前面使用了两个「%」,这是因为在注册表中,单个「%」会被解释为注册表变量,而不是命令行参数,用两次才会向输出一个「%」。保存后会立即生效:

效果

案例三:上传图片到图床

类似上传图片到图床之类的操作,我希望看到上传进度,其返回值也需要记录,因此需要小改下命令。

首先需要解决如何使用命令行实现上传图片的问题,我使用的是 picgo-core 工具。picgo-core 是 picgo 的命令行版本,客户端拥有的功能它都有。可以使用npm install picgo -g全局安装。至于配置、插件等使用问题,在这里不多赘述,可以参考 官方文档,网上相关教程也有很多。在写入右键之前,将它调整得符合自己使用习惯,并且确保能在终端中直接调用。其上传图片到默认图床的命令为:

picgo u 图片路径
上传图片

我们不妨继续在「图片处理」目录下添加命令,按照案例二中的结构新建「上传图片」和「command」项。从上面的图片演示中可以看到,picgo 会展示上传进度,最后返回一个图片的链接,我们需要复制这个链接。因此要让 PowerShell 执行完命令后不退出,等待用户下一步操作。实现 PowerShell 的等待只需要在命令后添加-noexit。在 command 的修改默认键值为powershell.exe -noexit picgo u %1

效果

美化和优化

基本功能设置完成后,还可以给菜单添加一点装饰。以「图片处理」菜单为例,选中它,在右侧面板添加字符串值,命名为「icon」,在其「数据」中写入图标文件的路径。这样,菜单文字前就会显示这个图标:

菜单图标

因为案例中的命令都用了 PowerShell,所以在执行命令后,Powershell 会出现一段时间然后消失,如果不太喜欢,可以在 PowerShell 设置中调整窗口位置和大小。打开 Powershell,在其设置的「布局」栏中勾掉「由系统定位窗口」,调整窗口位置和大小,把它放在角落。

放在角落

如果是多用户,需要注意,通过修改 HKEY_CLASSES_ROOT 来添加右键菜单是对电脑中所有用户生效的,相当于修改了系统的默认设置。HKCR 实际上是由 HKEY_LOCAL_MACHINE 和 HKEY_CURRENT_USER 的 Software\Classes 两部分混合(merge)而成。如果想要对单用户生效,就要把以上操作在 HKEY_CURRENT_USER 中完成。

完工后,选中添加的项目,右键导出,更换环境之后可以双击导出的文件直接写入注册表,免去重新设置的麻烦。

重要提醒

  • 注册表文件是系统的关键文件。虽然文中涉及的添加项目操作并不会对系统稳定性产生影响,但是,如果不慎删除或者修改了其他关键项目,将会产生难以挽回的后果
  • 系统自带的注册表编辑器并没有「撤销」的命令,一旦修改,就会立刻生效。
  • 建议首先备份相关注册表,编辑时要尽量小心。
  • 另外,添加过多的右键项目可能会导致卡顿。如非必要,建议在某个特定文件类型下添加菜单。
  • 本文展示的是简单的命令,复杂的操作仍然建议编写脚本或者依靠有 UI 的软件。

参考资料:

  1. 微软给出的新建静态右键菜单的说明
  2. 注册表的作用
  3. Windows 对 HKCR 的定义
  4. Magick 的详细用法和变量

> 下载少数派 客户端 、关注 少数派公众号 ,了解更妙的数字生活 🍃