【发布时间】:2014-12-30 10:26:29
【问题描述】:
我有一个应用程序,它的工作是启动和停止各种其他进程。
问题在于 Qt 应用程序不会完全停止。 Qt 窗口关闭,但进程仍然在后台运行,直到调用 TerminateProcess(),然后 Qt 应用程序退出而不进行清理。
我正在使用 Microsoft 概述的 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 通常知道什么时候需要退出,并且会干净利落地退出,除非开发人员搞砸了,您可以通过查看(不可用的)源代码来检查...
-
@SirDarius:这也是我的思考过程,但是在这个程序管理的所有应用程序中,只有 Qt 有这个问题(总共 3 个),而且它们都是由不同的作者编写的。巧合?此外,任务管理器可以干净地关闭它们,但是如何..?
-
我可能会建议您尝试停止第三方开源 qt 程序,例如您可以调试的 cmake gui 并查看它是如何实现的
-
也许 Qt (不正确地)期望 wParam 和/或 lParam 具有某些特定值?
-
@SirDarius:我刚刚尝试了 CMake gui。它有同样的问题 - 窗口关闭但进程仍然存在
标签: c++ windows qt winapi kill-process