我有一个无窗口应用程序,其唯一目的是安装一个32位钩子DLL文件并等待父程序(一个64位程序)退出。 64位程序是用C#编写的,而无窗口应用程序是用C++编写的。我本来有这个的GetMessage循环持有本程序打开:Win32无窗口应用程序 - 等待程序退出
while(GetMessage(&msg, NULL, 0, 0) > 0)
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
我关闭使用C#的Process.Kill方法的C++应用程序,但我发现,这是不允许的C++应用程序关闭干净。另外,如果C#应用程序崩溃,C++应用程序将永远保持打开状态。我提出的C++应用程序检查,看是否C#应用程序仍在运行,使用这种循环:
while(true)
{
if(PeekMessage(&msg, NULL, 0, 0, true))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!isMainProgramRunning())
break;
Sleep(1000);
}
出于某种原因,导致睡眠问题。由DLL文件安装的钩子是WH_CBT和WH_KEYBOARD。每当我按下一个键而C++应用程序正在运行此循环时,键就会被吃掉。去除睡眠使它工作正常,但是,正如所料,它使用100%我不想要的CPU。我试图完全删除消息循环,而是使用WaitForSingleObject在线程上有无限的超时,当isMainProgramRunning返回false时会结束。这基本上锁定了整个电脑。
我不明白为什么GetMessage,就我所见,它从来没有返回,但无限期地暂停主线程,并没有导致这些问题,但WaitForSingleObject导致每个应用程序冻结,当我点击它。我如何才能让C++应用程序在C#应用程序关闭之前保持打开状态?
编辑:
因为它已经向我指出,在消息泵睡不好,让我想问:有没有指定在等待消息超时的方式,所以程序不无限期地等待一条消息,而是等待大约250分钟,超时,让我运行isMainProgramRunning方法,然后再等一会儿?
EDIT2:
我用MsgWaitForMultipleObjects,虽然比狮子座稍微不同的方式试图建议。这是我使用的循环:
while(MsgWaitForMultipleObjects (0, NULL, true, 250, QS_ALLPOSTMESSAGE) != WAIT_FAILED)
{
if(PeekMessage(&msg, NULL, 0, 0, true))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(!isMainProgramRunning())
break;
}
我再次遇到与睡眠相同的问题。我也尝试暂停主线程,让另一个线程恢复。同样的问题。 GetMessage是什么让它可以等待而不会导致这些问题?也许这应该成为另一篇文章的主题,但为什么当安装钩子的C++应用程序休眠或挂起时,钩子中的所有处理似乎都暂停了?
EDIT3:
这里是,C++应用程序调用安装钩子的DLL方法:
extern "C" __declspec(dllexport) void install()
{
cbtHook = SetWindowsHookEx(WH_CBT, hookWindowEvents, hinst, NULL);
if(cbtHook == NULL)
MessageBox(NULL, "Unable to install CBT hook", "Error!", MB_OK);
keyHook = SetWindowsHookEx(WH_KEYBOARD, LowLevelKeyboardProc, hinst, NULL);
if(keyHook == NULL)
MessageBox(NULL, "Unable to install key hook", "Error!", MB_OK);
}
我有点怀疑这个。常规无窗应用程序如何保持开放状态? – Telanor 2010-12-20 20:55:45
我决定这么做,因为GetMessage似乎是唯一一个没有破坏所有东西的等待函数。 – Telanor 2010-12-22 06:15:49
-1:GetMessage可以在没有窗口的情况下使用。这不是答案,国际海事组织。如果MsgWaitForMultipleObject正确使用,它将不会返回(除非有线程唤醒的原因)。 PostThreadMessage上的MSDN显式地提到没有窗口的GetMessage:“发布消息的线程通过调用GetMessage或PeekMessage函数来检索消息,返回的MSG结构的hwnd成员为NULL。 – 2010-12-22 07:45:01