Electron.js(Node.js)跨平台获取已安装应用信息及打开应用的实现方法
嘿,我来帮你搞定Electron里获取已安装应用列表和打开指定应用的需求!下面分两部分给你讲清楚,还有完整的示例代码。
获取已安装应用列表
因为Windows、macOS、Linux的应用安装路径和注册方式差异很大,所以咱们得针对每个平台写不同的逻辑。这里用Node.js的child_process模块来执行系统命令,获取应用信息,再整理成你要的数组格式。
实现思路
- Windows: 读取系统级和用户级注册表的
Uninstall项,提取应用名称 - macOS: 用
mdfind命令搜索所有应用Bundle,或者直接遍历/Applications目录 - Linux: 遍历系统和用户目录下的
.desktop文件,从中提取应用名称
示例函数代码
const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); function thisFunctionShouldReturnInstalledApps() { let apps = []; const platform = process.platform; try { switch (platform) { case 'win32': // 读取系统+用户注册表的已安装应用信息 const regOutput = execSync( 'reg query HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall /s /v DisplayName 2>nul || reg query HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall /s /v DisplayName 2>nul', { encoding: 'utf-8' } ); // 提取DisplayName字段并去重 const winMatches = regOutput.match(/DisplayName\s+REG_SZ\s+(.+)/g); if (winMatches) { apps = winMatches.map(line => line.split('REG_SZ')[1].trim()).filter(Boolean); apps = [...new Set(apps)]; } break; case 'darwin': // 用mdfind搜索所有macOS应用 const macOutput = execSync( 'mdfind "kMDItemContentType=com.apple.application-bundle"', { encoding: 'utf-8' } ); const appPaths = macOutput.split('\n').filter(Boolean); apps = appPaths.map(appPath => path.basename(appPath, '.app')); apps = [...new Set(apps)]; break; case 'linux': // 遍历系统和用户的.desktop应用配置文件 const desktopDirs = [ '/usr/share/applications', path.join(process.env.HOME, '.local/share/applications') ]; desktopDirs.forEach(dir => { if (fs.existsSync(dir)) { const desktopFiles = fs.readdirSync(dir).filter(file => file.endsWith('.desktop')); desktopFiles.forEach(file => { const content = fs.readFileSync(path.join(dir, file), 'utf-8'); const nameMatch = content.match(/Name=(.+)/); if (nameMatch) apps.push(nameMatch[1]); }); } }); apps = [...new Set(apps)]; break; default: console.log('暂不支持当前操作系统'); } } catch (err) { console.error('获取已安装应用失败:', err); } return apps; }
打开指定应用
这里用Electron的shell模块的openPath方法,不过需要先根据应用名称找到对应的可执行文件/应用包路径,再执行打开操作。
实现思路
- Windows: 先用
where命令查找应用路径,找不到再从注册表提取安装位置 - macOS: 直接拼接
/Applications/{应用名称}.app路径 - Linux: 从
.desktop文件里提取Exec字段,获取可执行文件路径
示例函数代码
const { shell } = require('electron'); const { execSync } = require('child_process'); const fs = require('fs'); const path = require('path'); async function thisFunctionShouldOpenApp(appName) { const platform = process.platform; let appPath = ''; try { switch (platform) { case 'win32': // 优先用where命令找应用路径 try { appPath = execSync(`where ${appName}`, { encoding: 'utf-8' }).trim(); } catch { // where找不到的话,从注册表找安装位置 const regOutput = execSync( `reg query HKLM\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall /s /v DisplayName /v InstallLocation 2>nul || reg query HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall /s /v DisplayName /v InstallLocation 2>nul`, { encoding: 'utf-8' } ); const entries = regOutput.split('\n\n'); for (const entry of entries) { if (entry.includes(`DisplayName\\s+REG_SZ\\s+${appName}`)) { const locMatch = entry.match(/InstallLocation\s+REG_SZ\s+(.+)/); if (locMatch) { appPath = path.join(locMatch[1].trim(), `${appName}.exe`); break; } } } } break; case 'darwin': appPath = `/Applications/${appName}.app`; break; case 'linux': // 从.desktop文件提取可执行路径 const desktopDirs = [ '/usr/share/applications', path.join(process.env.HOME, '.local/share/applications') ]; for (const dir of desktopDirs) { if (fs.existsSync(dir)) { const desktopFiles = fs.readdirSync(dir).filter(file => file.endsWith('.desktop')); for (const file of desktopFiles) { const content = fs.readFileSync(path.join(dir, file), 'utf-8'); const nameMatch = content.match(/Name=(.+)/); if (nameMatch && nameMatch[1] === appName) { const execMatch = content.match(/Exec=(.+?)(\s|$)/); if (execMatch) { appPath = execMatch[1]; break; } } } if (appPath) break; } } break; default: console.log('暂不支持当前操作系统'); return; } if (appPath && fs.existsSync(appPath)) { await shell.openPath(appPath); console.log(`已打开应用:${appName}`); } else { console.log(`未找到应用:${appName}`); } } catch (err) { console.error('打开应用失败:', err); } }
测试代码
把上面两个函数放在Electron主进程中(因为访问系统资源和shell需要主进程权限),然后测试:
// 在主进程中执行 const installedApps = thisFunctionShouldReturnInstalledApps(); console.log(installedApps); // 打开Visual Studio Code(假设它在列表中) thisFunctionShouldOpenApp('Visual Studio Code');
注意事项
- 权限问题:Windows下读取部分注册表项可能需要管理员权限,Linux下遍历系统目录也需要对应权限
- 特殊应用无法检测:绿色版、便携版应用因为不在系统注册/标准目录下,可能无法被获取到
- 应用名称重复:部分应用可能存在多个版本,建议保留去重逻辑
内容的提问来源于stack exchange,提问作者dotslashroot
相关产品推荐
相关产品推荐

