From 1bfc18887a2c4c2864ead02f0f5edf571c31bb6f Mon Sep 17 00:00:00 2001 From: zmdyy0318 Date: Sat, 7 Nov 2026 22:43:55 +0800 Subject: [PATCH] =?UTF-8?q?fix(update):=20=E4=BB=BB=E5=8A=A1=E7=BB=93?= =?UTF-8?q?=E6=9D=9F=E5=90=8E=E8=87=AA=E5=8A=A8=E5=AE=89=E8=A3=85=E5=B9=B6?= =?UTF-8?q?=E9=87=8D=E5=90=AF=E6=97=B6=E4=B8=8D=E5=86=8D=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E8=87=AA=E5=8A=A8=E4=BB=BB=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit autostart / autoRunOnLaunch 的任务跑完后才触发自动安装,重启沿用原命令行参数, 新进程会再次分发同一批自动任务。记录本进程是否已成功启动过自动任务并写入更新完成信息, 重启后据此跳过自动执行;启动时先装挂起更新的场景不受影响。 Refs MaaEnd/MaaEnd#7160 --- src/App.tsx | 53 +++++++++++++++++--------- src/components/InstallConfirmModal.tsx | 1 + src/services/updateService.ts | 6 +++ src/stores/appStore.ts | 4 ++ src/stores/types.ts | 5 +++ 5 files changed, 50 insertions(+), 19 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index b5ab908f..6b8c4545 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -114,6 +114,26 @@ import { const log = loggers.app; +/** + * 分发自动执行任务(autostart / autoRunOnLaunch),启动成功时记录本次进程已执行过, + * 以便更新重启后跳过重复分发 + */ +function dispatchAutoStartTasks(onSettled?: (started: boolean) => void) { + document.dispatchEvent( + new CustomEvent('mxu-start-tasks', { + detail: { + source: 'autostart', + onSettled: (started: boolean) => { + if (started) { + useAppStore.getState().setAutoTasksRanInSession(true); + } + onSettled?.(started); + }, + }, + }), + ); +} + type LoadingState = 'loading' | 'success' | 'error'; // 页面过渡动画时长(ms) @@ -1069,25 +1089,24 @@ function App() { autoStartTasksPending = false; autoTaskLaunchPendingRef.current = true; setTimeout(() => { - document.dispatchEvent( - new CustomEvent('mxu-start-tasks', { - detail: { - source: 'autostart', - onSettled: () => { - autoTaskLaunchPendingRef.current = false; - // 启动失败时任务不会产生 running -> idle 状态变化,需要在这里补一次安装检查; - // 启动成功时仍处于运行态,本次检查会直接返回,并在任务结束后再次触发。 - tryAutoInstallUpdate(); - }, - }, - }), - ); + dispatchAutoStartTasks(() => { + autoTaskLaunchPendingRef.current = false; + // 启动失败时任务不会产生 running -> idle 状态变化,需要在这里补一次安装检查; + // 启动成功时仍处于运行态,本次检查会直接返回,并在任务结束后再次触发。 + tryAutoInstallUpdate(); + }); }, 500); }; // 检查是否刚更新完成(重启后) const isAutoStartModeNow = useAppStore.getState().isAutoStartMode; const updateCompleteInfo = consumeUpdateCompleteInfo(); + if (updateCompleteInfo?.autoTasksAlreadyRan && autoStartTasksPending) { + // 更新前本次进程已执行过自动任务(任务结束后才自动安装并重启), + // 重启沿用原命令行参数会再次进入自动执行,这里跳过以避免重复执行 + log.info('更新重启:更新前已执行过自动任务,跳过本次自动执行'); + autoStartTasksPending = false; + } if (updateCompleteInfo) { const currentVersionNow = result.interface.version || ''; @@ -1603,9 +1622,7 @@ function App() { pendingAutoTasksRef.current = false; log.info('下载失败或取消,分发挂起的自动任务'); setTimeout(() => { - document.dispatchEvent( - new CustomEvent('mxu-start-tasks', { detail: { source: 'autostart' } }), - ); + dispatchAutoStartTasks(); }, 500); } }, [downloadStatus]); @@ -1616,9 +1633,7 @@ function App() { pendingAutoTasksRef.current = false; log.info('弹窗关闭,分发挂起的自动任务'); setTimeout(() => { - document.dispatchEvent( - new CustomEvent('mxu-start-tasks', { detail: { source: 'autostart' } }), - ); + dispatchAutoStartTasks(); }, 500); } }, [showInstallConfirmModal]); diff --git a/src/components/InstallConfirmModal.tsx b/src/components/InstallConfirmModal.tsx index fd965072..8932c1de 100644 --- a/src/components/InstallConfirmModal.tsx +++ b/src/components/InstallConfirmModal.tsx @@ -116,6 +116,7 @@ export function InstallConfirmModal() { releaseNote: updateInfo.releaseNote, channel: updateInfo.channel, timestamp: Date.now(), + autoTasksAlreadyRan: useAppStore.getState().autoTasksRanInSession, }); } await restartApp(); diff --git a/src/services/updateService.ts b/src/services/updateService.ts index e60ffb6f..d858ef43 100644 --- a/src/services/updateService.ts +++ b/src/services/updateService.ts @@ -1280,6 +1280,12 @@ export interface UpdateCompleteInfo { * - false/undefined: 直接显示更新完成弹窗 */ requireVersionCheck?: boolean; + /** + * 安装前本次进程是否已成功启动过自动执行任务(autostart / autoRunOnLaunch) + * - true: 重启后不再分发自动任务,避免同一批任务重复执行 + * - false/undefined: 重启后按正常流程分发 + */ + autoTasksAlreadyRan?: boolean; } /** diff --git a/src/stores/appStore.ts b/src/stores/appStore.ts index 9990dac0..43c1445a 100644 --- a/src/stores/appStore.ts +++ b/src/stores/appStore.ts @@ -2115,6 +2115,10 @@ export const useAppStore = create()( isAutoStartMode: false, setIsAutoStartMode: (mode) => set({ isAutoStartMode: mode }), + // 本次进程内自动执行的任务是否已成功启动过 + autoTasksRanInSession: false, + setAutoTasksRanInSession: (ran) => set({ autoTasksRanInSession: ran }), + // 启动后自动执行的实例 ID autoStartInstanceId: undefined, setAutoStartInstanceId: (id) => diff --git a/src/stores/types.ts b/src/stores/types.ts index 7e565201..d32b5bc6 100644 --- a/src/stores/types.ts +++ b/src/stores/types.ts @@ -441,6 +441,11 @@ export interface AppState { isAutoStartMode: boolean; setIsAutoStartMode: (mode: boolean) => void; + // 本次进程内自动执行(autostart / autoRunOnLaunch)的任务是否已成功启动过 + // 用于更新重启后避免重复执行同一批自动任务 + autoTasksRanInSession: boolean; + setAutoTasksRanInSession: (ran: boolean) => void; + // 启动后自动执行的实例 ID autoStartInstanceId: string | undefined; setAutoStartInstanceId: (id: string | undefined) => void;