From 7ce7dfff84d9e4097c7f9ef822915cdc397107a7 Mon Sep 17 00:00:00 2001 From: icarus Date: Thu, 25 Dec 2025 20:42:25 +0800 Subject: [PATCH] fix(ovms): make ovms manager windows-only and lazy load it Add platform check in OvmsManager constructor to throw error on non-Windows platforms Lazy load ovmsManager instance and handle IPC registration only on Windows Update will-quit handler to conditionally cleanup ovms resources --- src/main/index.ts | 12 ++++++++--- src/main/ipc.ts | 35 ++++++++++++++++++++++---------- src/main/services/OvmsManager.ts | 9 +++++++- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/src/main/index.ts b/src/main/index.ts index ec16475d3f..b710389550 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -37,7 +37,6 @@ import { versionService } from './services/VersionService' import { windowService } from './services/WindowService' import { initWebviewHotkeys } from './services/WebviewService' import { runAsyncFunction } from './utils' -import { ovmsManager } from './services/OvmsManager' const logger = loggerService.withContext('MainEntry') @@ -158,7 +157,7 @@ if (!app.requestSingleInstanceLock()) { registerShortcuts(mainWindow) - registerIpc(mainWindow, app) + await registerIpc(mainWindow, app) localTransferService.startDiscovery({ resetList: true }) replaceDevtoolsFont(mainWindow) @@ -248,7 +247,14 @@ if (!app.requestSingleInstanceLock()) { app.on('will-quit', async () => { // 简单的资源清理,不阻塞退出流程 - await ovmsManager.stopOvms() + if (isWin) { + const { ovmsManager } = await import('./services/OvmsManager') + if (ovmsManager) { + await ovmsManager.stopOvms() + } else { + logger.warn('Unexpected behavior: undefined ovmsManager on Windows') + } + } try { await mcpService.cleanup() diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 8f86a93075..16ff339582 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -59,7 +59,6 @@ import NotificationService from './services/NotificationService' import * as NutstoreService from './services/NutstoreService' import ObsidianVaultService from './services/ObsidianVaultService' import { ocrService } from './services/ocr/OcrService' -import { ovmsManager } from './services/OvmsManager' import powerMonitorService from './services/PowerMonitorService' import { proxyManager } from './services/ProxyManager' import { pythonService } from './services/PythonService' @@ -120,7 +119,7 @@ function extractPluginError(error: unknown): PluginError | null { return null } -export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { +export async function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { const appUpdater = new AppUpdater() const notificationService = new NotificationService() @@ -974,15 +973,29 @@ export function registerIpc(mainWindow: BrowserWindow, app: Electron.App) { ipcMain.handle(IpcChannel.OCR_ListProviders, () => ocrService.listProviderIds()) // OVMS - ipcMain.handle(IpcChannel.Ovms_AddModel, (_, modelName: string, modelId: string, modelSource: string, task: string) => - ovmsManager.addModel(modelName, modelId, modelSource, task) - ) - ipcMain.handle(IpcChannel.Ovms_StopAddModel, () => ovmsManager.stopAddModel()) - ipcMain.handle(IpcChannel.Ovms_GetModels, () => ovmsManager.getModels()) - ipcMain.handle(IpcChannel.Ovms_IsRunning, () => ovmsManager.initializeOvms()) - ipcMain.handle(IpcChannel.Ovms_GetStatus, () => ovmsManager.getOvmsStatus()) - ipcMain.handle(IpcChannel.Ovms_RunOVMS, () => ovmsManager.runOvms()) - ipcMain.handle(IpcChannel.Ovms_StopOVMS, () => ovmsManager.stopOvms()) + if (isWin) { + const { ovmsManager } = await import('./services/OvmsManager') + if (ovmsManager) { + ipcMain.handle( + IpcChannel.Ovms_AddModel, + (_, modelName: string, modelId: string, modelSource: string, task: string) => { + if (ovmsManager) { + return ovmsManager.addModel(modelName, modelId, modelSource, task) + } else { + throw new Error('ovmsManager is undefined') + } + } + ) + ipcMain.handle(IpcChannel.Ovms_StopAddModel, () => ovmsManager.stopAddModel()) + ipcMain.handle(IpcChannel.Ovms_GetModels, () => ovmsManager.getModels()) + ipcMain.handle(IpcChannel.Ovms_IsRunning, () => ovmsManager.initializeOvms()) + ipcMain.handle(IpcChannel.Ovms_GetStatus, () => ovmsManager.getOvmsStatus()) + ipcMain.handle(IpcChannel.Ovms_RunOVMS, () => ovmsManager.runOvms()) + ipcMain.handle(IpcChannel.Ovms_StopOVMS, () => ovmsManager.stopOvms()) + } else { + logger.error('Unexpected behavior: undefined ovmsManager on Windows') + } + } // CherryAI ipcMain.handle(IpcChannel.Cherryai_GetSignature, (_, params) => generateSignature(params)) diff --git a/src/main/services/OvmsManager.ts b/src/main/services/OvmsManager.ts index 54e0a1bb8b..09836e1bbd 100644 --- a/src/main/services/OvmsManager.ts +++ b/src/main/services/OvmsManager.ts @@ -3,6 +3,7 @@ import { homedir } from 'node:os' import { promisify } from 'node:util' import { loggerService } from '@logger' +import { isWin } from '@main/constant' import { HOME_CHERRY_DIR } from '@shared/config/constant' import * as fs from 'fs-extra' import * as path from 'path' @@ -29,6 +30,12 @@ interface OvmsConfig { class OvmsManager { private ovms: OvmsProcess | null = null + constructor() { + if (!isWin) { + throw new Error('OVMS Manager is only supported on Windows platforms') + } + } + /** * Recursively terminate a process and all its child processes * @param pid Process ID to terminate @@ -563,4 +570,4 @@ class OvmsManager { } // Export singleton instance -export const ovmsManager = new OvmsManager() +export const ovmsManager = isWin ? new OvmsManager() : undefined