From 207334608c919c60ad1ceddbb9ecddfe249af329 Mon Sep 17 00:00:00 2001 From: momen Date: Wed, 11 Mar 2026 14:20:23 +0800 Subject: [PATCH] =?UTF-8?q?fix:=E5=B7=B2=E5=AE=89=E8=A3=85=E7=9A=84?= =?UTF-8?q?=E8=BD=AF=E4=BB=B6=E4=B8=8D=E6=98=BE=E7=A4=BA=E6=89=93=E5=BC=80?= =?UTF-8?q?=E8=BD=AF=E4=BB=B6=E7=9A=84=E6=8C=89=E9=92=AE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/main/backend/install-manager.ts | 59 +++++++++++++++++------- src/App.vue | 2 +- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/electron/main/backend/install-manager.ts b/electron/main/backend/install-manager.ts index 882ec54d..8b2b40a5 100644 --- a/electron/main/backend/install-manager.ts +++ b/electron/main/backend/install-manager.ts @@ -413,16 +413,43 @@ async function processNextInQueue() { } } -ipcMain.handle("check-installed", async (_event, pkgname: string) => { +// eslint-disable-next-line @typescript-eslint/no-explicit-any +ipcMain.handle("check-installed", async (_event, payload: any) => { + const pkgname = typeof payload === "string" ? payload : payload.pkgname; + const origin = typeof payload === "string" ? "spark" : payload.origin; + if (!pkgname) { logger.warn("check-installed missing pkgname"); return false; } - logger.info(`检查应用是否已安装: ${pkgname}`); + logger.info(`检查应用是否已安装: ${pkgname} (来源: ${origin})`); + + let isInstalled = false; + + if (origin === "apm") { + const { code, stdout } = await runCommandCapture("apm", ["list", "--installed"]); + if (code === 0) { + // eslint-disable-next-line no-control-regex + const cleanStdout = stdout.replace(/\x1b\[[0-9;]*m/g, ""); + const lines = cleanStdout.split("\n"); + for (const line of lines) { + const trimmed = line.trim(); + if (!trimmed || trimmed.startsWith("Listing") || trimmed.startsWith("[INFO]") || trimmed.startsWith("警告")) continue; + if (trimmed.includes("/")) { + const installedPkg = trimmed.split("/")[0].trim(); + if (installedPkg === pkgname) { + isInstalled = true; + logger.info(`应用已安装 (APM检测): ${pkgname}`); + break; + } + } + } + } + return isInstalled; + } const checkScript = "/opt/spark-store/extras/check-is-installed"; - let isInstalled = false; // 首先尝试使用内置脚本 if (fs.existsSync(checkScript)) { @@ -449,20 +476,20 @@ ipcMain.handle("check-installed", async (_event, pkgname: string) => { if (isInstalled) return true; } - // // 如果脚本不存在或检测不到,使用 dpkg-query 作为后备 - // logger.info(`尝试使用 dpkg-query 检测: ${pkgname}`); - // const { code } = await runCommandCapture("dpkg-query", [ - // "-W", - // "-f='${Status}'", - // pkgname, - // ]); + // 如果脚本不存在或检测不到,使用 dpkg-query 作为后备 + logger.info(`尝试使用 dpkg-query 检测: ${pkgname}`); + const { code, stdout } = await runCommandCapture("dpkg-query", [ + "-W", + "-f=${Status}", + pkgname, + ]); - // if (code === 0) { - // isInstalled = true; - // logger.info(`应用已安装 (dpkg-query 检测): ${pkgname}`); - // } else { - // logger.info(`应用未安装: ${pkgname}`); - // } + if (code === 0 && stdout.includes("install ok installed")) { + isInstalled = true; + logger.info(`应用已安装 (dpkg-query 检测): ${pkgname}`); + } else { + logger.info(`应用未安装 (dpkg-query 检测): ${pkgname}`); + } return isInstalled; }); diff --git a/src/App.vue b/src/App.vue index 542b1882..53d6f2f5 100644 --- a/src/App.vue +++ b/src/App.vue @@ -466,7 +466,7 @@ const openDetail = (app: App | Record) => { const checkAppInstalled = (app: App) => { window.ipcRenderer - .invoke("check-installed", app.pkgname) + .invoke("check-installed", { pkgname: app.pkgname, origin: app.origin }) .then((isInstalled: boolean) => { currentAppIsInstalled.value = isInstalled; });