跳到主要内容

命令(Command):VS Code 界面 → 插件代码

命令是什么​

用户在 VS Code 里点的按钮、命令面板里的条目,最终都会带上一个字符串 commandId(例如 hardware-core-monitor.startMonitoring)。VS Code 把这个 ID 发给 Extension Host,执行你在代码里注册的 回调函数。

需要两处配合:

  1. package.json:声明命令叫什么、图标是什么、出现在哪个菜单(只负责「展示和绑定 ID」)。
  2. src/extension.ts:vscode.commands.registerCommand(id, 回调)(负责「真正干什么」)。

本项目的 commandId 列表​

在 package.json 的 contributes.commands 里声明:

commandId用户在哪里看到
hardware-core-monitor.startMonitoring侧栏标题栏 ▶(Play)
hardware-core-monitor.stopMonitoring侧栏标题栏 ⏸(Pause)
hardware-core-monitor.refreshMonitoring侧栏标题栏刷新
hardware-core-monitor.showDashboard命令面板等(打开仪表盘 Webview)
hardware-core-monitor.showWebview2命令面板等(打开 Webview2)

侧栏标题栏按钮在 package.json → contributes.menus → view/title 里绑定到上述 ID,例如刷新按钮:

{
"command": "hardware-core-monitor.refreshMonitoring",
"when": "view == hardware-core-monitor.sidebarView",
"group": "navigation@1"
},

通信方向:VS Code UI 收到点击 → 发送 commandId → Extension Host 运行对应 registerCommand 的回调。


vscode.commands.registerCommand 做什么​

作用:把 commandId 和一段 JavaScript 函数绑在一起;绑定的返回值是 Disposable,插件卸载时要释放。

在本项目的位置:src/extension.ts 的 activate() 里。

开始监控​

const startMonitoring = vscode.commands.registerCommand(
"hardware-core-monitor.startMonitoring",
() => {
monitorService.updateInterval(getRefreshIntervalMs());
monitorService.start();
void vscode.commands.executeCommand(
"setContext",
MONITORING_CONTEXT,
true,
);
void vscode.window.showInformationMessage(text.monitor.started());
},
);

回调里做了四件事:读配置间隔、启动 MonitorService、改上下文键(控制 Pause/Play 显示)、弹出提示。后两项也是 VS Code API,见其他文档。

停止监控​

const stopMonitoring = vscode.commands.registerCommand(
"hardware-core-monitor.stopMonitoring",
() => {
monitorService.stop();
void vscode.commands.executeCommand(
"setContext",
MONITORING_CONTEXT,
false,
);
void vscode.window.showInformationMessage(text.monitor.paused());
},
);

立即刷新一次数据​

const refreshMonitoring = vscode.commands.registerCommand(
"hardware-core-monitor.refreshMonitoring",
() => {
monitorService.requestNow();
},
);

打开 Webview 面板(本系列文档不展开 Webview 内部)​

const showDashboard = vscode.commands.registerCommand(
"hardware-core-monitor.showDashboard",
() => {
DashboardPanel.createOrShow(context, monitorService);
},
);

const showWebview2 = vscode.commands.registerCommand(
"hardware-core-monitor.showWebview2",
() => {
Webview2Panel.createOrShow(context, monitorService);
},
);

注册后如何交给 VS Code 管理​

activate 末尾把这些 disposable 放进 context.subscriptions,扩展停用时 VS Code 会自动 dispose:

context.subscriptions.push(
monitorService,
treeView,
statusBar,
alerter,
startMonitoring,
stopMonitoring,
refreshMonitoring,
showDashboard,
showWebview2,
configChangeDisposable,
);

vscode.commands.executeCommand 做什么​

作用:主动触发某个 commandId(可以是 VS Code 内置命令,也可以是别的扩展注册的命令)。

本项目:改 UI 状态用的内置命令 setContext​

常量定义:

/** 控制活动栏标题按钮显示状态的上下文键 */
const MONITORING_CONTEXT = "hardwareMonitorIsRunning";

在「开始/停止/侧栏隐藏」时调用:

void vscode.commands.executeCommand(
"setContext",
MONITORING_CONTEXT,
true,
);

这不是业务命令,而是告诉 VS Code:把名为 hardwareMonitorIsRunning 的上下文设为 true/false,这样 package.json 里 when: "!hardwareMonitorIsRunning" / when: "hardwareMonitorIsRunning" 的 Play/Pause 按钮会切换显示。详见 05-context-keys-and-when.md。

状态栏点击 → 再走命令​

statusBarController.ts 没有 registerCommand,而是给状态栏项指定 点击时要执行的 commandId:

// 点击状态栏打开 React 仪表盘
this.item.command = "hardware-core-monitor.showDashboard";

通信链:用户点状态栏 → VS Code 执行 showDashboard 命令 → 上面注册的回调打开 DashboardPanel。


和 activate 的关系​

只有 package.json 里写了 command、菜单也绑了 ID,但 activate 里没有 registerCommand 时,用户点击不会有效果。

本插件在 onStartupFinished 时激活(package.json),随后 extension.ts 的 activate 完成全部 register。