广告位 · 页头(后台-模块管理-新建模块后替换此区域)

如何在 Vue 3 中工程化集成昂达显卡工具实现 GPU 监控?

在 Vue 3 项目中集成昂达显卡工具,本质上是把桌面端硬件工具的能力移植到 Web 侧。由于昂达显卡工具通常运行在 Windows 环境,前端浏览器无法直接与本地进程通信,因此需要借助 Node.js 后端作为桥梁。整条链路分为三层:硬件工具负责采集数据,后端服务负责调用和转换,前端负责展示和交互。

如何在 Vue 3 中工程化集成昂达显卡工具实现 GPU 监控?

一、摸清昂达显卡工具的命令行能力

昂达显卡工具本身提供了一个图形界面,用于调节频率、查看温度等。但对于工程化集成来说,图形界面无法被程序直接调用,我们需要确认它是否附带命令行参数。大多数硬件监控工具都会保留无界面模式,例如在安装目录下执行 onda-gpu-tool.exe --query 可以输出一段 JSON 文本。假设你的工具路径为 C:\Program Files\Onda\GPU Tool\onda-gpu-tool.exe,可以直接在终端测试。

onda-gpu-tool.exe --query

执行成功后,终端会打印类似下面的结果:

{
  "gpu": "Onda RTX 3060",
  "temperature": 62,
  "usage": 78,
  "fanSpeed": 2100,
  "memoryUsed": 4096,
  "memoryTotal": 12288
}

这个 JSON 结构就是我们后端要解析的目标。如果昂达显卡工具的参数名称不同,比如某些版本使用 --info 或 --output json,请先运行 onda-gpu-tool.exe --help 查看帮助。关键点在于稳定地拿到标准输出,后续处理就非常容易。

注意安装路径中的空格,在命令行直接运行时需要加双引号,但通过 Node.js 的 execFile 调用时,空格不会造成问题,因为参数会以数组形式传递。

二、用 Node.js 封装数据采集接口

后端服务的任务是定时调用命令行工具,把 JSON 字符串解析成对象,并通过 HTTP 接口暴露给前端。这里选择 Express 框架,因为它足够轻量,适合中小型监控服务。核心调用使用 Node.js 内置的 child_process.execFile,它比 exec 更安全,不会经过 shell 解析,可以避免路径和参数注入问题。

const express = require('express');
const { execFile } = require('child_process');
const app = express();
const PORT = 3000;
const TOOL_PATH = 'C:\\Program Files\\Onda\\GPU Tool\\onda-gpu-tool.exe';
function queryGpu() {
  return new Promise((resolve, reject) => {
    execFile(TOOL_PATH, ['--query'], { encoding: 'utf8' }, (error, stdout) => {
      if (error) {
        reject(error);
        return;
      }
      try {
        const data = JSON.parse(stdout);
        resolve(data);
      } catch (parseError) {
        reject(parseError);
      }
    });
  });
}
app.get('/api/gpu', async (req, res) => {
  try {
    const data = await queryGpu();
    res.json({
      success: true,
      data,
      timestamp: Date.now()
    });
  } catch (err) {
    res.status(500).json({
      success: false,
      message: err.message
    });
  }
});
app.listen(PORT, () => {
  console.log(`GPU monitor service running at http://127.0.0.1:${PORT}`);
});

上面代码中,TOOL_PATH 使用了双反斜杠进行转义,这是 JavaScript 字符串的标准写法。如果昂达显卡工具安装在另一个分区,比如 D:\Onda\Tool\onda-gpu-tool.exe,只需修改这一行即可。此外,如果工具在首次运行时需要管理员权限,请确保启动 Node.js 服务的终端具有相应权限,否则会触发 EACCES 错误。

为了让前端能跨域调用,开发阶段有两种做法:一是在 Express 中启用 CORS 中间件,二是在 Vite 的 dev server 中配置代理。推荐使用 Vite 代理,这样前端代码中的请求路径可以写成相对地址,部署时更灵活。

三、Vue 3 前端组件与实时展示

前端使用 Vite 创建的 Vue 3 项目,搭配 ECharts 绘制温度趋势。组件内部采用组合式 API 管理状态和定时器。通过 <script setup> 语法糖,可以少写很多样板代码。

<template>
  <div class="gpu-panel">
    <h2>昂达显卡状态</h2>
    <div class="metrics">
      <div class="metric">
        <span>温度</span>
        <strong>{{ gpuData.temperature }}°C</strong>
      </div>
      <div class="metric">
        <span>占用率</span>
        <strong>{{ gpuData.usage }}%</strong>
      </div>
      <div class="metric">
        <span>风扇转速</span>
        <strong>{{ gpuData.fanSpeed }} RPM</strong>
      </div>
    </div>
    <div ref="chartRef" class="chart"></div>
  </div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';
import axios from 'axios';
import * as echarts from 'echarts';
const gpuData = ref({
  temperature: 0,
  usage: 0,
  fanSpeed: 0,
  memoryUsed: 0,
  memoryTotal: 0
});
const chartRef = ref(null);
let chartInstance = null;
let timer = null;
async function fetchGpuData() {
  try {
    const response = await axios.get('/api/gpu');
    if (response.data.success) {
      gpuData.value = response.data.data;
      updateChart(response.data.data);
    }
  } catch (error) {
    console.error('获取显卡数据失败:', error.message);
  }
}
function updateChart(data) {
  if (!chartInstance) return;
  chartInstance.setOption({
    xAxis: { type: 'category', data: [new Date().toLocaleTimeString()] },
    yAxis: { type: 'value' },
    series: [{
      type: 'line',
      data: [data.temperature],
      smooth: true
    }]
  });
}
onMounted(async () => {
  chartInstance = echarts.init(chartRef.value);
  await fetchGpuData();
  timer = setInterval(fetchGpuData, 2000);
});
onBeforeUnmount(() => {
  if (timer) clearInterval(timer);
  if (chartInstance) chartInstance.dispose();
});
</script>

这段代码使用相对路径 /api/gpu 请求数据,因此不会出现跨域问题,只要 Vite 的代理配置正确即可。轮询间隔设置为 2000 毫秒,如果显卡工具本身支持事件推送,也可以把后端改成 WebSocket 方式,减少不必要的请求。

ECharts 的初始化和销毁都放在生命周期钩子中,避免组件卸载后定时器继续运行造成内存泄漏。如果需要在多个组件中复用这一逻辑,建议把数据获取部分提取成组合式函数 useGpuMonitor,这样可以提高代码的工程化程度。

四、生产环境下的工程化加固

开发环境跑通以后,生产部署还需要考虑几个问题:工具路径的可配置性、服务进程守护、前端构建后的静态资源托管。路径配置建议写入 .env 文件,通过 process.env.ONDA_TOOL_PATH 读取,这样不同机器上的路径差异不会影响代码。

import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';
export default defineConfig({
  plugins: [vue()],
  server: {
    proxy: {
      '/api': {
        target: 'http://127.0.0.1:3000',
        changeOrigin: true
      }
    }
  }
});

进程守护推荐使用 pm2,将 Node.js 服务注册为系统服务,即使崩溃也能自动拉起。同时,如果昂达显卡工具本身会定期弹出窗口,需要检查是否有静默模式参数,否则服务运行时会受到 GUI 干扰。还可以把轮询逻辑从请求驱动改为定时任务,将最新数据缓存到内存,减少对命令行工具的频繁调用,从而降低 CPU 开销。

最后提醒一句,如果昂达显卡工具没有提供公开的命令行文档,建议先联系厂商或查看安装目录下的说明文件。以上方案的核心思想是通用的:任何能输出文本的本地工具,都可以通过 Node.js 封装成 HTTP 服务,再交给 Vue 3 前端展示。掌握了这条链路,后续接入其他硬件监控工具也会非常顺手。

广告位 · 文章底部(后台-模块管理替换此区域)