gpt4 book ai didi

c++ - 终止 Qt 进程 : What's Windows Task Manager doing that I'm not?

转载 作者:可可西里 更新时间:2023-11-01 13:44:24 26 4
gpt4 key购买 nike

我有一个应用程序,它的工作是启动和停止各种其他进程。

问题是 Qt 应用程序不会干净地停止。 Qt 窗口关闭,但进程仍在后台运行,直到调用 TerminateProcess(),然后 Qt 应用程序退出而不进行清理。

我正在使用 this method如微软所述。即使是 Qt source使用该方法终止进程,除了他们还发布了 WM_CLOSE到主线程。我也将它添加到我的应用程序中,但它仍然只是关闭窗口,离开进程。

我觉得有趣的是,如果我使用 Windows 任务管理器“结束任务”(而不是“结束进程”),窗口会关闭,进程也会结束,所以我知道这是可能的。如果我使用 spy++,我可以看到主窗口和主线程都从任务管理器和我的应用程序接收到 WM_CLOSE 消息,但只有通过使用任务管理器,消息才会继续到 WM_DESTROY、WM_NCDESTROY 等,并以进程结束结束.此问题仅发生在 Qt 应用程序中。 Win32/MFC 等应用程序使用我的应用程序干净地终止。

您应该如何彻底关闭 Qt 应用程序(假设 Qt 应用程序源不可用)?

--------编辑--------

下面是一些可以重现问题的示例代码。至少,我很想知道其他人是否遇到了我遇到的同样问题。

示例代码启动 CMake ( download here ),但任何 Qt 应用程序都应该这样做。

#include <Windows.h>
#include <iostream>

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid);

int _tmain(int argc, _TCHAR* argv[])
{
char* processName = "C:\\Program Files (x86)\\CMake\\bin\\cmake-gui.exe";
//char* processName = "C:\\Windows\\Notepad.exe";

std::cout << "Creating process \"" << processName << "\"" << std::endl;

STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi = {0};

BOOL success = CreateProcess(processName,
"",
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi);

if (success)
{
std::cout << "Press any key to cleanly terminate process..." << std::endl;
std::cin.get();

std::cout << "Cleanly terminating process..." << std::endl;

EnumWindows(TerminateAppEnum, (LPARAM)pi.dwProcessId);
PostThreadMessage(pi.dwThreadId, WM_CLOSE, 0, 0);

if (WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0)
{
std::cout << "Success! The process has terminated" << std::endl;
}
else
{
std::cout << "Failed! The process is still running" << std::endl;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
{
std::cout << "Unable to start process (Error " << GetLastError() << ")" << std::endl;
}
std::cout << "Press any key to exit..." << std::endl;
std::cin.get();

return 0;
}

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid)
{
DWORD dwPID;
GetWindowThreadProcessId(hwnd, &dwPID);

if (dwPID == (DWORD)pid)
{
PostMessage(hwnd, WM_CLOSE, 0, 0);
}

return TRUE;
}

最佳答案

好的,解决了。

问题来自 Qt 创建顶级窗口的事实 - QEventDispatcher 窗口。按照 Microsoft 概述的过程,此窗口会收到一条 WM_CLOSE 消息,该消息会关闭该窗口及其线程。之后,当应用程序的主窗口关闭时,不会进行任何清理,该进程仍保留在系统内存中。

有趣的是,通过使用任务管理器,QEventDispatcher 不会获得 WM_CLOSE 消息,因此保持事件状态,因此当主窗口接收到 WM_CLOSE 消息时,进程会干净地退出。我只能假设对类似 IsWindowVisible 的调用正在使用 EnumWindowsProc callback在任务管理器中,与他们的 documentation 相反.尽管该文档上次审查是在十年前!

添加对 IsWindowVisible 的调用使该程序适用于所有 Qt 应用程序,其他非 Qt 应用程序似乎也很乐意继续使用此更改。为了完整起见,我包含了更新的示例代码:

#include <Windows.h>
#include <iostream>

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid);

int _tmain(int argc, _TCHAR* argv[])
{
char* processName = "C:\\Program Files (x86)\\CMake\\bin\\cmake-gui.exe";
//char* processName = "C:\\Windows\\Notepad.exe";

std::cout << "Creating process \"" << processName << "\"" << std::endl;

STARTUPINFO si = {0};
si.cb = sizeof(STARTUPINFO);
PROCESS_INFORMATION pi = {0};

BOOL success = CreateProcess(processName,
"",
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi);

if (success)
{
std::cout << "Press any key to cleanly terminate process..." << std::endl;
std::cin.get();

std::cout << "Cleanly terminating process..." << std::endl;

EnumWindows(TerminateAppEnum, (LPARAM)pi.dwProcessId);

if (WaitForSingleObject(pi.hProcess, 10000) == WAIT_OBJECT_0)
{
std::cout << "Success! The process has terminated" << std::endl;
}
else
{
std::cout << "Failed! The process is still running" << std::endl;
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
{
std::cout << "Unable to start process (Error " << GetLastError() << ")" << std::endl;
}
std::cout << "Press any key to exit..." << std::endl;
std::cin.get();

return 0;
}

BOOL CALLBACK TerminateAppEnum(HWND hwnd, LPARAM pid)
{
DWORD dwPID;
GetWindowThreadProcessId(hwnd, &dwPID);

if (dwPID == (DWORD)pid)
{
if (IsWindowVisible(hwnd))
{
PostMessage(hwnd, WM_CLOSE, 0, 0);
}
}

return TRUE;
}

关于c++ - 终止 Qt 进程 : What's Windows Task Manager doing that I'm not?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26719761/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com