У меня есть приложение без окон, единственной целью которого является установка 32-битного DLL-файла ловушки и ожидание выхода из родительской программы (64-битная программа).64-битная программа написана на C #, а приложение без окон написано на C ++.Первоначально у меня был этот цикл GetMessage, который удерживал программу открытой:
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 ++ работает с этим циклом, ключи просто съедаются.Удаление Sleep заставляет его работать нормально, но, как и ожидалось, он использует 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:
Вот метод DLL, который приложение C ++ вызывает для установки ловушек:
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);
}