使用 WSL 在 Windows 资源管理器上重新实现 lrzip 解压缩

使用 WSL 在 Windows 资源管理器上重新实现 lrzip 解压缩

我下载了旧版本的lrzip 解压工具对于 Windows,并注意到它正在使用 cygwin 库来运行程序本身。

WSL2 和 cygwin 的基准测试表明,wsl2很多更快,所以我想使用当前 WSL Ubuntu 安装中的 lrzip 二进制文件获取类似于该程序的东西。

不过,我还有两个问题。

  1. 如何将wsl正确的文件路径传递给命令(考虑这样的命令:wsl lrzip -d <compressed file to decompress>,也许还考虑到将解压的文件与压缩文件放在同一个文件夹中会更好)

  2. 如何在资源管理器菜单中集成这样的脚本(当您右键单击 .lrz 文件时,“lrzip 解压缩程序”会显示“解压缩”命令而不是“打开”命令)

提前致谢,抱歉,但在谈论 Windows 脚本方面我真的是个菜鸟 ('-_-)

答案1

概括
  • wslpath将 Windows 路径转换为 ​​WSL 等效路径

  • 创建一个脚本来转换路径,但一定要使用适当的引用来调用它以处理 Windows 路径中的反斜杠。

  • 创建注册表项以添加 WSL 脚本的右键单击,并用单引号括住'%1'表示文件名的项。例如:

    wsl -e bash -c "~/.local/bin/lrzipWP '%1'"
    
但首先 ...

在这种情况下,实际上有一个比“怎么做?”,这就是,“去哪儿做?”

正如@DanielB 在评论中提到的,你不得体验你希望通过 WSL2 实现的速度提升(剧透警告:“将不会”)。WSL2 比 Cygwin 更快,但部分优势来自于它利用自己的虚拟磁盘,可以在其中公开原生 ext4 文件系统。

因此对于处理文件里面那个文件系统,是的,WSL2 很棒。但是,当您使用 Windows 文件系统上的文件时,情况就完全不同了。WSL2 通过 9P 协议的网络客户端/服务器实现(显然是 localhost)访问 Windows 驱动器上的文件。WSL2 在 Windows 端运行服务器,WSL2 实例通过客户端实现访问文件(尽管它实际上是双向运行的)。

对于您访问的情况多个小文件在 Windows 驱动器上,WSL2 是非常慢 —— 可能比“本机” Windows 访问慢两个数量级。

我不太确定“大文件”用例会如何lrzip工作,所以我在 535MB 的 Ubuntu 服务器云映像上进行了测试。虽然不是很大,但不幸的是,结果相当糟糕:

# From Linux filesystem:

~/tmp> lrzip -d ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img.lrz
Output filename is: ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img
Decompressing...
100%     535.69 /    535.69 MB
Average DeCompression Speed: 133.750MB/s
Output filename is: ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img: [OK] - 561709056 bytes
Total time: 00:00:03.35

# Using Windows filesystem:
lrzip -d /mnt/c/temp/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img.lrz
Output filename is: /mnt/c/temp/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img
Decompressing...
100%     535.69 /    535.69 MB
Average DeCompression Speed:  9.068MB/s
Output filename is: /mnt/c/temp/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img: [OK] - 561709056 bytes

Total time: 00:00:58.26

这是一个非常快的 NVMe 驱动器。

解决方法

但不要绝望。仍然有一个好方法可以从 WSL 中做到这一点;只是不是 WSL2

WSL1 仍然存在且可行是有原因的。它仍然有一些出色的用例,这就是其中之一(附注:简化的网络访问是另一个)。

虽然 WSL2 有自己的虚拟文件系统(只要您使用该文件系统,速度就很快),但 WSL1 实际上直接地访问 Windows 驱动器。

与 WSL1 相同的测试?

lrzip -d /mnt/c/temp/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img.lrz
Output filename is: /mnt/c/temp/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img
Decompressing...
100%     535.69 /    535.69 MB
Average DeCompression Speed: 133.750MB/s
Output filename is: /mnt/c/temp/ubuntu-20.04-server-cloudimg-amd64-disk-kvm.img: [OK] - 561709056 bytes

Total time: 00:00:04.64

因此,一定要使用 WSL1 实例。

如果这是您使用 WSL 的唯一原因,只需使用以下命令转换您的实例:

wsl --set-version <distroname> 1

如果您想保留这两个版本,这也是完全可能的:

wsl --export <distroname> filename.tar
mkdir <where you want to place the second instance>
wsl --import <newdistroname> <location> filename.tar --version 1
剧本

那么(您说是时候了?)现在开始您的实际的问题 ...

要传递 Windows 路径,您需要有一个要调用的包装器 shell 脚本。我们将其称为lrzipWP(用于 Windows 路径)。

将 Windows 路径转换为 ​​WSL/Linux 是使用该wslpath命令完成的,该命令实际上(在我看来,相当有创意)在启动时注入到每个 WSL 实例中(通过/init将命令名称链接到其自身)。

-O并且可以通过获取文件的目录名称来获取要用于参数dirname的文件的目录名称。不过,在尝试之后,您不需要它,因为lrzipLinux 中的默认行为是使用与文件位置相同的目录。为了灵活性,我将把它留在脚本中,以防您出于某种原因需要它。

由于您将从右键单击菜单启动它,因此终端将在脚本退出时立即关闭,因此您需要添加一个read语句(或类似语句)来暂停,以便您可以读取输出。

把它们放在一起,你的脚本应该(希望)看起来像这样:

#!/usr/bin/env bash
lrzip -d $(wslpath "${1}") -O $(dirname $(wslpath "${1}"))
echo "Press <Enter> to Exit"
read

将其保存为类似 的内容~/.local/bin

使用 授予其可执行权限chmod +x ~/.local/bin/lrzipWP

现在您可以通过以下方式从 PowerShell 调用它:

wsl -e bash -c "~/.local/bin/lrzipWP 'C:\temp\filename.lrz'"
.lrz添加文件右键菜单

虽然这在 Super User 的其他地方已经讨论过了各种问题和答案,基本内容如下:

  • regedit在 Windows 中运行
  • 导航至Computer -> HKEY_CLASSES_ROOT(很简单,它就在顶部)。
  • 右键单击HKEY_CLASSES_ROOT新建 -> 密钥
  • 命名密钥.lrz
  • 右键单击.lrz新建 -> 密钥再次。
  • 命名此键shell
  • 右键单击shell新建 -> 密钥再次。
  • 命名此键lrz
  • 双击(Default)的属性lrz并将其更改为“使用 WSL lrz 解压缩”
  • 右键单击该lrz键并新建 -> 密钥(最后一次)。
  • 命名此键command
  • 双击(Default)的属性command并将其更改为:
    wsl -e bash -c "~/.local/bin/lrzipWP '%1'"
    

那应该(希望)可以做到。

相关内容