厌倦了 nvm-windows 的命令行?我造了一个 nvm GUI

0 阅读3分钟

项目地址:gitee.com/pancilandta…

前言

在 Windows 上管理 Node.js 版本,nvm-windows 几乎是唯一选择。但它只有命令行,每次切版本都要敲命令,而且因为涉及到 C:\Program Files\nodejs 的符号链接,每次启动都必须以管理员身份运行,UAC 弹窗烦不胜烦。

所以我用 PySide6 + pyside6-fluent-widgets 写了一个图形化界面,名字叫 nvmp。本来只是想给 nvm 套个皮,结果越写越上头,顺手把虚拟列表、异步操作、零 UAC 启动全做进去了。

效果预览

useImage.png

界面是 Fluent Design 风格,自动跟随系统深色/浅色主题。顶部显示当前 Node 版本和已安装数量,两个标签页分别展示已安装版本和可下载版本,右侧搜索框可以实时过滤。

核心特性

  • 虚拟列表:可用版本有 800 多个,一次性渲染所有 DOM 会卡成 PPT。nvmp 用了虚拟化方案,只渲染视口内的行,滚动非常丝滑。
  • 异步操作:安装、卸载、切换版本都是异步执行的,进度直接打在界面上,窗口永远不会卡死。
  • 一键搜索:输入关键字实时过滤版本号,找 LTS 版本很方便。
  • 零 UAC 启动:安装时只弹一次 UAC,之后从开始菜单或桌面启动再也不用弹窗。这个后面会详细讲实现原理。

零 UAC 是怎么做到的?

这是我觉得最值得分享的一个技术点。

nvm-windows 需要管理员权限的本质原因是它要操作 C:\Program Files\nodejs 目录和创建符号链接。所以 nvmp 本身也必须以管理员身份运行,否则调不动 nvm。

常规做法有三种:

  1. 每次启动都右键"以管理员身份运行"——最烦,pass。
  2. 给可执行文件加 requireAdministrator manifest——双击自动提权,但每次都会弹 UAC。
  3. 用计划任务(Scheduled Task)预授权——安装时以管理员身份注册一个最高权限计划任务,之后启动时通过 schtasks /Run 触发该任务,Windows 直接以管理员身份启动进程,不再弹 UAC。

nvmp 选了方案 3,具体流程如下:

  1. 安装阶段:Inno Setup 安装器请求一次管理员权限,然后通过 PowerShell 的 Register-ScheduledTask 注册一个名为 nvmp 的计划任务,设置 RunLevel=Highest,并且不给它设置任何触发器(这样它不会自动运行)。
  2. 启动阶段:开始菜单和桌面的快捷方式并不直接指向 nvmp.exe,而是指向一个 VBS 脚本 nvmp_launcher.vbs。这个脚本隐藏地调用 schtasks /Run /TN nvmp,Windows 直接拉起预授权的高权限任务,nvmp 以管理员身份启动,全程无感。
  3. 卸载阶段:Inno Setup 的 [UninstallRun] 自动执行 schtasks /Delete,清理计划任务。

这样用户只要忍受一次安装时的 UAC,后续所有启动都是静默的。

技术栈

技术
语言Python 3.13
GUI 框架PySide6 6.11
组件库pyside6-fluent-widgets 1.11
打包PyInstaller (onedir + windowed)
安装器Inno Setup 6
依赖管理uv

Fluent Widgets 这套组件库质感确实不错,配合 PySide6 的 QUiLoader 可以在 Qt Designer 里把 .ui 布局文件画好,运行时直接加载,开发和调整界面都很方便。

快速开始

普通用户

直接下载 release/nvmp-0.1.0-setup.exe 安装即可。安装完成后从开始菜单或桌面启动,享受零 UAC。

开发者

git clone https://gitee.com/pancilandtao/nvmp.git
cd nvmp
uv sync
uv run python main.py

打包安装器:

uv run python build_installer.py

输出在 dist/installer/nvmp-0.1.0-setup.exe

写在最后

这个小工具本质上就是对 nvm-windows 的封装,没有特别高深的技术,但在细节上做了一点优化:虚拟列表解决大列表卡顿、异步操作避免 UI 卡死、计划任务解决 UAC 烦扰。如果你也在 Windows 上用 nvm,欢迎试试,提 Issue 或者 PR 都可以。


项目地址:gitee.com/pancilandta…

如果对你有帮助,欢迎点个 Star。