From 52b130198299360e83812a7481303117b26089d0 Mon Sep 17 00:00:00 2001 From: benya Date: Sun, 15 Feb 2026 18:51:00 +0300 Subject: [PATCH] fix(update): wait for app exit before file replacement --- main.py | 17 ++++++++++++----- tests/test_auth_relogin_smoke.py | 2 ++ 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/main.py b/main.py index af955ca..acde39d 100644 --- a/main.py +++ b/main.py @@ -835,7 +835,7 @@ class VkChatManager(QMainWindow): return candidate return extracted_dir - def _build_update_script(self, app_dir, source_dir, exe_name): + def _build_update_script(self, app_dir, source_dir, exe_name, target_pid): script_path = os.path.join(tempfile.gettempdir(), "anabasis_apply_update.cmd") script_lines = [ "@echo off", @@ -843,8 +843,15 @@ class VkChatManager(QMainWindow): f"set APP_DIR={app_dir}", f"set SRC_DIR={source_dir}", f"set EXE_NAME={exe_name}", - "timeout /t 2 /nobreak >nul", - "robocopy \"%SRC_DIR%\" \"%APP_DIR%\" /E /NFL /NDL /NJH /NJS /NP /R:3 /W:1 >nul", + f"set TARGET_PID={target_pid}", + ":wait_for_exit", + "tasklist /FI \"PID eq %TARGET_PID%\" | find \"%TARGET_PID%\" >nul", + "if %ERRORLEVEL% EQU 0 (", + " timeout /t 1 /nobreak >nul", + " goto :wait_for_exit", + ")", + "timeout /t 1 /nobreak >nul", + "robocopy \"%SRC_DIR%\" \"%APP_DIR%\" /E /NFL /NDL /NJH /NJS /NP /R:12 /W:2 >nul", "set RC=%ERRORLEVEL%", "if %RC% GEQ 8 goto :copy_error", "start \"\" \"%APP_DIR%\\%EXE_NAME%\"", @@ -892,7 +899,7 @@ class VkChatManager(QMainWindow): app_exe = sys.executable app_dir = os.path.dirname(app_exe) exe_name = os.path.basename(app_exe) - script_path = self._build_update_script(app_dir, source_dir, exe_name) + script_path = self._build_update_script(app_dir, source_dir, exe_name, os.getpid()) creation_flags = 0 if hasattr(subprocess, "CREATE_NEW_PROCESS_GROUP"): @@ -911,7 +918,7 @@ class VkChatManager(QMainWindow): "Обновление запущено", "Обновление скачано. Приложение будет перезапущено.", ) - QTimer.singleShot(150, QApplication.instance().quit) + QApplication.instance().quit() return True except Exception as e: self._log_event("auto_update_failed", str(e), level="ERROR") diff --git a/tests/test_auth_relogin_smoke.py b/tests/test_auth_relogin_smoke.py index 6562190..f45744a 100644 --- a/tests/test_auth_relogin_smoke.py +++ b/tests/test_auth_relogin_smoke.py @@ -46,6 +46,8 @@ class AuthReloginSmokeTests(unittest.TestCase): self.assertIn('message_box.addButton("Обновить сейчас", QMessageBox.AcceptRole)', self.source) self.assertIn("def _start_auto_update(self, download_url, latest_version, checksum_url=\"\", download_name=\"\"):", self.source) self.assertIn("def _verify_update_checksum(self, zip_path, checksum_url, download_name):", self.source) + self.assertIn("def _build_update_script(self, app_dir, source_dir, exe_name, target_pid):", self.source) + self.assertIn("set TARGET_PID=", self.source) if __name__ == "__main__":