前言
对于前端开发者而言,Electron 与鸿蒙 OS 的组合,是低成本切入鸿蒙生态的最优解之一。无需学习 ArkTS 原生开发,仅凭 HTML/CSS/JS 技术栈,就能开发出适配鸿蒙设备的桌面应用。
前面的文章已经讲解了基础开发流程和进阶功能,本文将聚焦实用性,开发一个 “鸿蒙系统工具箱”,集成设备信息查询、文件快速搜索、系统命令执行三大核心功能。全程提供可直接运行的代码,帮助开发者快速打造一款实用的鸿蒙桌面工具。
一、功能定位与核心优势
1. 工具功能清单
| 功能模块 | 核心能力 | 鸿蒙适配要点 |
|---|---|---|
| 设备信息查询 | 查看 CPU、内存、系统版本、磁盘占用等 | 调用 Node.js 系统模块,适配鸿蒙设备目录结构 |
| 文件快速搜索 | 根据文件名关键词搜索鸿蒙设备内文件 | 遍历鸿蒙设备文件系统,优化搜索算法提升效率 |
| 系统命令执行 | 执行ls、pwd、top等 Linux 命令 | 适配鸿蒙 Linux 兼容层,支持命令结果实时输出 |
2. 核心优势
- 轻量化:无冗余依赖,打包后体积小,运行内存占用低;
- 实用性:功能贴合鸿蒙设备日常使用需求;
- 易扩展:模块化代码结构,可快速添加新功能(如进程管理、网络测速)。
二、环境搭建
沿用基础开发环境,无需额外配置:
- 鸿蒙 OS 3.0+ 设备(开启开发者模式、Linux 兼容层);
- Node.js 16.x LTS + Electron 22.x + electron-packager;
- VS Code(安装 Electron 插件提升开发效率)。
安装核心依赖:
bash
运行
# 初始化项目 mkdir harmony-electron-toolbox && cd harmony-electron-toolbox npm init -y # 安装核心依赖 npm install electron@22.3.2 --save npm install nodemon --save-dev # 热重载开发依赖修改package.json配置脚本:
json
{ "name": "harmony-electron-toolbox", "version": "1.0.0", "main": "main.js", "scripts": { "start": "nodemon --exec electron .", "package": "electron-packager . harmony-toolbox --platform=linux --arch=x64 --out=dist" }, "devDependencies": { "nodemon": "^3.1.0" }, "dependencies": { "electron": "^22.3.2" } }三、核心代码实现
1. 项目结构
plaintext
harmony-electron-toolbox/ ├── main.js # 主进程:功能逻辑+IPC通信 ├── preload.js # 通信桥接:暴露安全API ├── index.html # 渲染进程:UI界面+交互 └── package.json # 项目配置2. 主进程:main.js
主进程是工具的核心,负责文件搜索、命令执行、系统信息查询,并通过 IPC 与渲染进程通信。
javascript
运行
const { app, BrowserWindow, ipcMain } = require('electron'); const path = require('path'); const fs = require('fs'); const { exec } = require('child_process'); const os = require('os'); let mainWindow; // 创建应用窗口 function createWindow() { mainWindow = new BrowserWindow({ width: 1000, height: 700, title: '鸿蒙系统工具箱', webPreferences: { nodeIntegration: true, contextIsolation: false, // 鸿蒙兼容必需配置 preload: path.join(__dirname, 'preload.js') }, frame: false, // 鸿蒙扁平化窗口样式 titleBarStyle: 'hidden' }); mainWindow.loadFile('index.html'); mainWindow.webContents.openDevTools(); // 调试用,发布时关闭 // 窗口关闭事件 mainWindow.on('closed', () => { mainWindow = null; }); } // ========== 功能1:获取设备信息 ========== ipcMain.on('get-device-info', (event) => { try { const deviceInfo = { 系统版本: os.version(), 主机名: os.hostname(), CPU核心数: os.cpus().length, CPU型号: os.cpus()[0].model, 总内存: (os.totalmem() / 1024 / 1024 / 1024).toFixed(2) + ' GB', 空闲内存: (os.freemem() / 1024 / 1024 / 1024).toFixed(2) + ' GB', 磁盘根目录占用: getDiskUsage('/') }; event.reply('device-info-reply', { success: true, data: deviceInfo }); } catch (error) { event.reply('device-info-reply', { success: false, message: error.message }); } }); // 辅助函数:获取磁盘占用 function getDiskUsage(dir) { try { const stats = fs.statfs(dir); const total = (stats.blocks * stats.blockSize) / 1024 / 1024 / 1024; const free = (stats.bfree * stats.blockSize) / 1024 / 1024 / 1024; const used = (total - free).toFixed(2) + ' GB / ' + total.toFixed(2) + ' GB'; return used; } catch (error) { return '获取失败'; } } // ========== 功能2:文件快速搜索 ========== ipcMain.on('search-files', (event, keyword) => { if (!keyword) { event.reply('search-files-reply', { success: false, message: '请输入搜索关键词' }); return; } const results = []; // 搜索鸿蒙设备常用目录:用户目录 + 根目录 const searchDirs = [os.homedir(), '/']; searchDirs.forEach(dir => { try { searchDir(dir, keyword, results); } catch (error) { // 忽略无权限目录 } }); event.reply('search-files-reply', { success: true, data: results.slice(0, 50) }); // 限制最多返回50条 }); // 递归搜索目录 function searchDir(dir, keyword, results) { const files = fs.readdirSync(dir, { withFileTypes: true }); for (const file of files) { const fullPath = path.join(dir, file.name); // 文件名包含关键词则加入结果 if (file.name.toLowerCase().includes(keyword.toLowerCase())) { results.push({ name: file.name, path: fullPath, type: file.isDirectory() ? '文件夹' : '文件' }); } // 递归搜索子文件夹 if (file.isDirectory()) { try { searchDir(fullPath, keyword, results); } catch (error) { continue; } } } } // ========== 功能3:执行系统命令 ========== ipcMain.on('exec-command', (event, cmd) => { if (!cmd) { event.reply('command-output', '请输入要执行的命令'); return; } // 执行Linux命令,适配鸿蒙Linux兼容层 exec(cmd, { maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => { if (error) { event.reply('command-output', `执行失败:${error.message}`); return; } if (stderr) { event.reply('command-output', `错误输出:${stderr}`); return; } event.reply('command-output', `执行结果:\n${stdout}`); }); }); // ========== 窗口控制 ========== ipcMain.on('window-control', (event, action) => { switch (action) { case 'minimize': mainWindow.minimize(); break; case 'close': mainWindow.close(); break; } }); // 应用启动 app.whenReady().then(createWindow); app.on('window-all-closed', () => { if (process.platform !== 'darwin') app.quit(); }); app.on('activate', () => { if (BrowserWindow.getAllWindows().length === 0) createWindow(); });3. 预加载脚本:preload.js
作为渲染进程与主进程的安全通信桥梁,暴露核心功能 API。
javascript
运行
const { ipcRenderer, contextBridge } = require('electron'); contextBridge.exposeInMainWorld('toolboxAPI', { // 获取设备信息 getDeviceInfo: () => { return new Promise((resolve) => { ipcRenderer.send('get-device-info'); ipcRenderer.once('device-info-reply', (event, data) => { resolve(data); }); }); }, // 搜索文件 searchFiles: (keyword) => { return new Promise((resolve) => { ipcRenderer.send('search-files', keyword); ipcRenderer.once('search-files-reply', (event, data) => { resolve(data); }); }); }, // 执行系统命令 execCommand: (cmd) => { ipcRenderer.send('exec-command', cmd); }, // 监听命令输出 onCommandOutput: (callback) => { ipcRenderer.on('command-output', (event, data) => { callback(data); }); }, // 窗口控制 windowControl: (action) => { ipcRenderer.send('window-control', action); } });4. 渲染进程:index.html
采用鸿蒙扁平化设计风格,实现三大功能的 UI 与交互逻辑。
html
预览
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>鸿蒙系统工具箱</title> <style> * { margin: 0; padding: 0; box-sizing: border-box; font-family: "HarmonyOS Sans SC", sans-serif; } body { background-color: #f5f5f7; color: #1d1d1f; } /* 鸿蒙风格标题栏 */ .title-bar { display: flex; justify-content: space-between; align-items: center; padding: 12px 20px; background-color: #fff; border-bottom: 1px solid #e5e5e7; } .title { font-size: 18px; font-weight: 500; } .control-btns button { width: 32px; height: 32px; border: none; background: transparent; border-radius: 50%; cursor: pointer; font-size: 16px; margin-left: 8px; } .control-btns button:hover { background-color: #f0f0f2; } /* 功能标签页 */ .tabs { display: flex; background-color: #fff; border-bottom: 1px solid #e5e5e7; } .tab-btn { padding: 12px 24px; border: none; background: transparent; font-size: 16px; cursor: pointer; position: relative; } .tab-btn.active { color: #007aff; } .tab-btn.active::after { content: ''; position: absolute; bottom: -1px; left: 0; width: 100%; height: 2px; background-color: #007aff; } /* 功能内容区 */ .content { padding: 20px; height: calc(100vh - 110px); overflow-y: auto; } .tab-content { display: none; } .tab-content.active { display: block; } /* 通用样式:卡片、输入框、按钮 */ .card { background-color: #fff; border-radius: 12px; padding: 20px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.05); } .input-box { width: 100%; padding: 12px 16px; border: 1px solid #e5e5e7; border-radius: 8px; font-size: 16px; margin-bottom: 16px; outline: none; } .input-box:focus { border-color: #007aff; } .btn { padding: 12px 24px; background-color: #007aff; color: #fff; border: none; border-radius: 8px; font-size: 16px; cursor: pointer; } .btn:hover { background-color: #0066cc; } /* 设备信息样式 */ .info-list { display: grid; grid-template-columns: repeat(2, 1fr); gap: 16px; } .info-item { padding: 12px; background-color: #f5f5f7; border-radius: 8px; } .info-label { font-size: 14px; color: #86868b; margin-bottom: 4px; } .info-value { font-size: 16px; font-weight: 500; } /* 文件搜索结果样式 */ .search-result { margin-top: 16px; max-height: 400px; overflow-y: auto; } .result-item { padding: 12px; border-bottom: 1px solid #e5e5e7; display: flex; justify-content: space-between; } .result-item:last-child { border-bottom: none; } .result-path { font-size: 14px; color: #86868b; } /* 命令执行样式 */ .command-output { width: 100%; height: 400px; padding: 16px; border: 1px solid #e5e5e7; border-radius: 8px; background-color: #f5f5f7; font-family: monospace; font-size: 14px; white-space: pre-wrap; overflow-y: auto; } </style> </head> <body> <!-- 标题栏 --> <div class="title-bar"> <div class="title">鸿蒙系统工具箱</div> <div class="control-btns"> <button onclick="window.toolboxAPI.windowControl('minimize')">—</button> <button onclick="window.toolboxAPI.windowControl('close')">✕</button> </div> </div> <!-- 功能标签页 --> <div class="tabs"> <button class="tab-btn active" onclick="switchTab('device-info')">设备信息</button> <button class="tab-btn" onclick="switchTab('file-search')">文件搜索</button> <button class="tab-btn" onclick="switchTab('command-exec')">命令执行</button> </div> <!-- 功能内容区 --> <div class="content"> <!-- 设备信息面板 --> <div class="tab-content active" id="device-info"> <div class="card"> <h3 style="margin-bottom: 16px;">设备基础信息</h3> <div class="info-list" id="device-info-list"> <div class="info-item"> <div class="info-label">加载中...</div> </div> </div> </div> </div> <!-- 文件搜索面板 --> <div class="tab-content" id="file-search"> <div class="card"> <input type="text" class="input-box" id="search-keyword" placeholder="请输入要搜索的文件名关键词..."> <button class="btn" onclick="searchFiles()">开始搜索</button> <div class="search-result" id="search-result"></div> </div> </div> <!-- 命令执行面板 --> <div class="tab-content" id="command-exec"> <div class="card"> <input type="text" class="input-box" id="command-input" placeholder="请输入Linux命令(如ls、pwd、top -n 1)..."> <button class="btn" onclick="execCommand()">执行命令</button> <div class="command-output" id="command-output">请输入命令并执行...</div> </div> </div> </div> <script> // 页面加载初始化 window.addEventListener('DOMContentLoaded', () => { loadDeviceInfo(); // 监听命令输出 window.toolboxAPI.onCommandOutput((output) => { document.getElementById('command-output').textContent = output; }); }); // 切换标签页 function switchTab(tabId) { // 切换标签按钮状态 document.querySelectorAll('.tab-btn').forEach(btn => { btn.classList.remove('active'); if (btn.onclick.toString().includes(tabId)) { btn.classList.add('active'); } }); // 切换内容面板状态 document.querySelectorAll('.tab-content').forEach(panel => { panel.classList.remove('active'); }); document.getElementById(tabId).classList.add('active'); } // 加载设备信息 async function loadDeviceInfo() { const result = await window.toolboxAPI.getDeviceInfo(); const listEl = document.getElementById('device-info-list'); if (!result.success) { listEl.innerHTML = `<div class="info-item"><div class="info-value">${result.message}</div></div>`; return; } let html = ''; for (const [key, value] of Object.entries(result.data)) { html += ` <div class="info-item"> <div class="info-label">${key}</div> <div class="info-value">${value}</div> </div> `; } listEl.innerHTML = html; } // 搜索文件 async function searchFiles() { const keyword = document.getElementById('search-keyword').value.trim(); const resultEl = document.getElementById('search-result'); resultEl.innerHTML = '<div style="padding: 12px; text-align: center;">搜索中...</div>'; const result = await window.toolboxAPI.searchFiles(keyword); if (!result.success) { resultEl.innerHTML = `<div style="padding: 12px; color: #ff3b30;">${result.message}</div>`; return; } if (result.data.length === 0) { resultEl.innerHTML = '<div style="padding: 12px; text-align: center;">未找到匹配文件</div>'; return; } let html = ''; result.data.forEach(item => { html += ` <div class="result-item"> <div>${item.name} <span style="color: #007aff;">(${item.type})</span></div> <div class="result-path">${item.path}</div> </div> `; }); resultEl.innerHTML = html; } // 执行系统命令 function execCommand() { const cmd = document.getElementById('command-input').value.trim(); window.toolboxAPI.execCommand(cmd); } </script> </body> </html>四、调试与部署
1. 本地调试
在项目根目录执行命令启动应用,测试功能是否正常:
bash
运行
npm start可分别测试设备信息查询、文件搜索、命令执行功能,调试 UI 样式与交互逻辑。
2. 鸿蒙设备部署
(1)打包应用
执行打包命令,生成鸿蒙兼容的 Linux-x64 版本:
bash
运行
npm run package打包完成后,在dist目录下会生成harmony-toolbox-linux-x64文件夹。
(2)运行应用
- 将打包后的文件夹拷贝到鸿蒙设备;
- 打开鸿蒙设备终端,进入应用目录,赋予执行权限:
bash
运行
cd /home/user/Documents/harmony-toolbox-linux-x64 chmod +x harmony-toolbox - 启动应用:
bash
运行
./harmony-toolbox
3. 常见问题排查
| 问题现象 | 解决方案 |
|---|---|
| 文件搜索无结果 | 检查搜索关键词是否正确,鸿蒙设备是否有对应文件;忽略无权限目录的报错 |
| 命令执行失败 | 确保输入的是 Linux 命令,鸿蒙设备已开启 Linux 兼容层;部分命令需要 root 权限 |
| 应用启动白屏 | 检查main.js中contextIsolation是否设为false |
五、总结与扩展
本文开发的鸿蒙系统工具箱,是一个轻量化、高实用性的 Electron 应用,核心亮点在于:
- 功能贴合鸿蒙设备使用场景,解决实际需求;
- 代码模块化程度高,便于拓展新功能;
- 完全基于前端技术栈,零成本适配鸿蒙系统。
拓展方向
- 添加进程管理功能:查看 / 结束鸿蒙设备进程;
- 集成网络测速:测试鸿蒙设备的网络上传 / 下载速度;
- 支持文件快捷操作:双击搜索结果打开文件 / 文件夹;
- 打包为 HAP 安装包,发布到鸿蒙应用市场。
文末标签
#鸿蒙OS #Electron #跨端开发 #前端开发 #系统工具 #代码实战
欢迎大家加入[开源鸿蒙跨平台开发者社区](https://openharmonycrossplatform.csdn.net),一起共建开源鸿蒙跨平台生态。