From 60cbc68e59ddf7115dc81bcdf556427c5812d2bd Mon Sep 17 00:00:00 2001 From: Jin Zhaonian <86561727+glimmertouch@users.noreply.github.com> Date: Mon, 27 Apr 2026 01:36:19 +0800 Subject: [PATCH] =?UTF-8?q?fear:=20PC=20=E7=AB=AF=E6=94=AF=E6=8C=81=20`?= =?UTF-8?q?=E5=AE=8C=E6=88=90=E5=90=8E=E9=80=80=E5=87=BA=E6=98=8E=E6=97=A5?= =?UTF-8?q?=E6=96=B9=E8=88=9F`=20(#16351)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 修复pc端任务完成后勾选自动关闭游戏但无法关闭的问题 * fix: IsWindow检查与WM_CLOSE关闭 Co-authored-by: Copilot --------- Co-authored-by: Copilot --- src/MaaCore/Controller/Win32Controller.cpp | 68 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/src/MaaCore/Controller/Win32Controller.cpp b/src/MaaCore/Controller/Win32Controller.cpp index 0c1a89e930..c57a353b9e 100644 --- a/src/MaaCore/Controller/Win32Controller.cpp +++ b/src/MaaCore/Controller/Win32Controller.cpp @@ -135,8 +135,72 @@ bool Win32Controller::start_game(const std::string& client_type [[maybe_unused]] bool Win32Controller::stop_game(const std::string& client_type [[maybe_unused]]) { - Log.warn("stop_game is not supported on Win32Controller"); - return false; + LogTraceFunction; + + if (!m_hwnd) { + Log.info("No window handle available, game may already be closed"); + return true; + } + + HWND hwnd = static_cast(m_hwnd); + if (!IsWindow(hwnd)) { + Log.info("Invalid or stale window handle, game may already be closed, hwnd:", m_hwnd); + return true; + } + + DWORD pid = 0; + DWORD tid = GetWindowThreadProcessId(hwnd, &pid); + if (tid == 0) { + DWORD error = GetLastError(); + Log.error("Failed to get thread/process id from hwnd, hwnd:", m_hwnd, "last_error:", error); + return false; + } + + if (pid == 0) { + Log.error("Failed to get process id from hwnd, hwnd:", m_hwnd); + return false; + } + + HANDLE hProcess = OpenProcess(PROCESS_TERMINATE | SYNCHRONIZE, FALSE, pid); + if (!hProcess) { + DWORD error = GetLastError(); + Log.error("Failed to open process, pid:", pid, "last_error:", error); + return false; + } + + if (PostMessage(hwnd, WM_CLOSE, 0, 0)) { + DWORD wait_result = WaitForSingleObject(hProcess, 5000); + if (wait_result == WAIT_OBJECT_0) { + CloseHandle(hProcess); + Log.info("Game process closed gracefully, pid:", pid); + return true; + } + } + + BOOL ok = TerminateProcess(hProcess, 0); + if (!ok) { + DWORD error = GetLastError(); + CloseHandle(hProcess); + Log.error("Failed to terminate process, pid:", pid, "last_error:", error); + return false; + } + + DWORD wait_result = WaitForSingleObject(hProcess, 5000); + CloseHandle(hProcess); + + if (wait_result == WAIT_TIMEOUT) { + Log.error("Terminate process timed out, pid:", pid); + return false; + } + + if (wait_result == WAIT_FAILED) { + DWORD error = GetLastError(); + Log.error("Wait for process termination failed, pid:", pid, "last_error:", error); + return false; + } + + Log.info("Game process terminated, pid:", pid); + return true; } bool Win32Controller::click(const Point& p)