I have a windowless application whose sole purpose is to install a 32-bit DLL file with a hook and wait for the completion of the parent program (64-bit program). A 64-bit program is written in C #, and a windowless application is written in C ++. Initially, I had this GetMessage loop in which the program was opened:
while(GetMessage(&msg, NULL, 0, 0) > 0) { TranslateMessage(&msg); DispatchMessage(&msg); }
I closed the C ++ application using the Process.Kill method in C #, but I found out that this does not allow closing the C ++ application. Also, if a C # application crashes, the C ++ application will remain open forever. I did a C ++ application check to see if a C # application was working all using this loop:
while(true) { if(PeekMessage(&msg, NULL, 0, 0, true)) { TranslateMessage(&msg); DispatchMessage(&msg); } if(!isMainProgramRunning()) break; Sleep(1000); }
For some reason, Sleep causes problems. The hooks set by the DLL file are WH_CBT and WH_KEYBOARD. Whenever I press a key when a C ++ application is working with this loop, the keys just eat it. Removing sleep makes it work fine, but, as expected, it uses 100% CPU , which I don't want. I tried to completely delete the message loop and instead use WaitForSingleObject with an infinite timeout in the thread, which will end when isMainProgramRunning returns false. This basically blocks the entire computer.
I really donโt understand why GetMessage, which, as I saw it, never returned, but suspended the main thread indefinitely, has not yet caused these problems. WaitForSingleObject makes each application freeze when I click on it. How can I make a C ++ application remain open until the C # application closes?
Edit:
Since I was told that sleeping in a pump message is bad, let me ask: is there a way to indicate the waiting time for a waiting message, so the program does not wait indefinitely for a message, but rather, it will wait about 250 ฮผs, timeout, let me run isMainProgramRunning method, and then wait again?
Edit2:
I tried using MsgWaitForMultipleObjects, although in a slightly different way than Leo suggested. This is the loop I used:
while(MsgWaitForMultipleObjects (0, NULL, true, 250, QS_ALLPOSTMESSAGE) != WAIT_FAILED) { if(PeekMessage(&msg, NULL, 0, 0, true)) { TranslateMessage(&msg); DispatchMessage(&msg); } if(!isMainProgramRunning()) break; }
Again I had the same problem with Sleep. I also tried to pause the main thread and resume it. Same problem. What does GetMessage do that allows it to wait without causing these problems? Maybe this should be the subject of another message, but why is it that when a C ++ application setting hooks is sleeping or paused, all hook processing is also paused?
Edit3:
Here is the DLL method that a C ++ application calls to install hooks:
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); }