【发布时间】:2021-11-13 16:01:39
【问题描述】:
我在我的 dll 中创建了一个虚拟窗口作为 IPC 方法:
窗口程序:
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_COPYDATA:
{
//....
}
case WM_DESTROY:
case WM_QUIT:
OutputDebugString(L"WM_QUIT");
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
int Main(LPCWSTR dummy_class_name)
{
WNDCLASSEX wc{};
//HWND dummy_hwnd;
MSG Msg;
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = 0;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = dummy_class_name;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc))
{
MessageBox(NULL, L"Window Registration Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
dummy_hwnd = CreateWindowEx(WS_EX_LEFT, // this is the default
dummy_class_name, // the name of the class, as passed to the RegisterClass function
NULL, // Title
0, // dwFlags, in our case this really doesn't matter
0, // X
0, // Y
0, // W
0, // H
HWND_MESSAGE , //the most important flag! Creates a message-only window
0, // hMenu
0 , // hInstance this function gets the instance handle of the current app
0 // lpParam
);
if(dummy_hwnd == NULL)
{
MessageBox(NULL, L"Window Creation Failed!", L"Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(dummy_hwnd, SW_SHOW);
UpdateWindow(dummy_hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return 0; // Msg.wParam;
}
我在辅助线程上初始化窗口过程:
class std::future<void> thread;
void Foo() {
// ...
thread = std::async(std::launch::async, [dummy_class_name]
{ Main(dummy_class_name); });
}
但是,当我与 dll 挂钩的进程“退出”时,它仍处于“休眠”状态。
当我不调用Foo 函数时,它会完全退出。
我尝试挂接目标进程函数ExitCode 并使用WM_QUIT、WM_DESTROY 调用WndProc 函数,它确实收到了消息,但进程仍然保持打开状态。
void ExitProcess_Hook(UINT uExitCode)
{
OutputDebugString(L"\nExitProcess_Hook!");
//PostMessageW(dummy_hwnd, WM_DESTROY, 0, 0);
WndProc(dummy_hwnd, WM_DESTROY, 0, 0);
return ExitProcess(uExitCode);
}
我错过了什么?
【问题讨论】:
-
尝试调用
TerminateProcess- "..因此,如果您不知道进程中所有线程的状态,最好调用TerminateProcess而不是ExitProcess。..." docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/… -
@RichardCritten 谢谢,TerminateProcess 确实有效。你能把它作为答案吗?
-
@RichardCritten 如果您不知道进程中所有线程的状态 - 但这几乎总是如此。但并不意味着需要致电
TerminateProcess。如果进程挂在 ExitProcess 中 - 这意味着编码错误。并使用TerminateProcess- 快速解决方案,而不是研究、理解和修复错误 -
你应该在某处发布一个最小的复制项目。 stackoverflow.com/help/minimal-reproducible-example