// electron/modules/vscode-extension.ts - VS Code 插件安装模块 import { BrowserWindow } from 'electron' import { execa } from 'execa' import { getVscodeCliPath } from './utils' import logger from './logger' /** * 发送状态到渲染进程 */ function sendToRenderer(channel: string, data: unknown): void { const windows = BrowserWindow.getAllWindows() windows.forEach((win) => { win.webContents.send(channel, data) }) } /** * 安装 VS Code 插件 * 供 IPC handler 和 installer.ts 复用 * @param extensionId 插件 ID * @returns 安装结果 */ export async function installVscodeExtension(extensionId: string): Promise<{ success: boolean; error?: string }> { try { const codePath = await getVscodeCliPath() const fullCommand = `${codePath} --install-extension ${extensionId}` logger.installInfo(`开始安装 VS Code 插件: ${extensionId},使用 CLI: ${codePath}`) // 使用 install-status 事件发送日志,这样可以被 App.vue 中的监听器捕获 sendToRenderer('install-status', { software: 'vscode', message: `正在安装 VS Code 插件: ${extensionId}...`, progress: 30, i18nKey: 'log.vscodeExtInstalling', i18nParams: { extensionId } }) // 发送执行命令的日志 sendToRenderer('install-status', { software: 'vscode', message: `执行命令: ${fullCommand}`, progress: 40, i18nKey: 'log.executingCommand', i18nParams: { command: fullCommand } }) const result = await execa(codePath, ['--install-extension', extensionId], { encoding: 'utf8', stdout: 'pipe', stderr: 'pipe' }) // 记录命令输出 if (result.stdout) { logger.installInfo(`VS Code 插件安装输出: ${result.stdout}`) sendToRenderer('install-status', { software: 'vscode', message: `code 输出: ${result.stdout}`, progress: 80, i18nKey: 'log.vscodeExtOutput', i18nParams: { output: result.stdout } }) } logger.installInfo(`VS Code 插件安装成功: ${extensionId}`) sendToRenderer('install-status', { software: 'vscode', message: `✅ VS Code 插件安装成功: ${extensionId}`, progress: 100, i18nKey: 'log.vscodeExtInstallSuccess', i18nParams: { extensionId } }) return { success: true } } catch (error) { const execaError = error as { message?: string; stderr?: string; shortMessage?: string } // 过滤乱码字符,只保留可读字符(ASCII 可打印字符和中文) let errorMessage = execaError.shortMessage || execaError.message || '未知错误' if (execaError.stderr) { const stderrClean = execaError.stderr.replace(/[^\x20-\x7E\u4e00-\u9fa5\n\r]/g, '').trim() if (stderrClean) { errorMessage = stderrClean } } // 从错误消息中也过滤乱码 errorMessage = errorMessage.replace(/[^\x20-\x7E\u4e00-\u9fa5\n\r:.\-_/\\]/g, '').trim() logger.installError(`VS Code 插件安装失败: ${extensionId}`, error) // 发送错误到渲染进程的安装日志 sendToRenderer('install-status', { software: 'vscode', message: `❌ VS Code 插件安装失败: ${errorMessage}`, progress: 0, i18nKey: 'log.vscodeExtInstallFailed', i18nParams: { extensionId, error: errorMessage } }) return { success: false, error: errorMessage } } }