I have a C++ Win32 application written using Win32 API and I wish to force it to exit in one of functions. Is there something like Exit() or Destroy() or Abort() something similar that would just terminate it?
Aiiieeeeeeeeeeee. Don't do ANY of these things!
exit() and ExitProcess are the equivalent of taking a gun and shooting the process in the face. I hope I don't have to explain why that isn't nice, especially for processes that are holding shared objects like database handles that might be system-wide. I know that's the norm in Android, but this is Windows and we don't do that 'round here.
Calling PostQuitMessage() directly can cause memory leaks. PostQuitMessage() is intended to be called from WM_DESTROY. It is NOT NOT NOT a message intended to be used to ask a window to close. It's a callback mechanism for applications to post their exit code back to the shell. It is intended to populate WM_QUIT with the application exit code. If you call PostQuitMessage() directly, you will bypass WM_DESTROY entirely. This is problematic because many windows--and child widgets--very correctly perform their clean-up in WM_DESTROY. If you skip this message by lying to the window, you will deny components the chance to clean up.
And since we're on the topic, don't call WM_DESTROY directly either. Raymond Chen of Microsoft has a wonderful article where he explains "Sending a window a WM_DESTROY message is like prank calling somebody pretending to be the police". It's sort of the evil-twin of PostQuitMessage. Instead of exiting without cleaning up, you're asking the window to clean up without exiting. The window manager never knows to remove the components, and you're left with a dead orphan window in memory. Sigh.
The correct answer is to post WM_CLOSE. Anything using the default window procedure will correctly notify the window manager to destroy the window which will cascade on to WM_DESTROY then to WM_QUIT as intended.
If you need different behavior than the standard close, the other alternative is to create a WM_USER or WM_APP message. If your window has a "fancy" WM_CLOSE--say, for example, you give the user a prompt "Are you sure you want to exit?"--and you want to skip that, you may define a custom message with WM_USER or WM_APP and call that in its place. Your app-defined message would implement the default close behavior, and the WM_CLOSE that's tied to the system gadgets performs your fancy behavior.
I hope that helps!
PostQuitMessage() is the standard, graceful way of quitting a windowed application.
It will not immediately quit but rather post a quit message that will get parsed by your main loop (if done correctly) and then quit the application.
If you're using a Win32 application with a proper window procedure, you can use the function PostQuitMessage.
If you're working with visual C++, then use:
PostQuitMessage()
ExitProcess is the function to use, else you can use exit, note that neither insure the integrity of the shutdown (ie: you many leak handles etc and threaded operations will be terminated, even if they are halfway through an operation, like a db commit)
Yes, it's exit()
http://www.cplusplus.com/reference/clibrary/cstdlib/exit/
Just return from the WinMain function. If you have a message loop, use PostQuitMessage to break out. Don't try to exit the process in the middle of execution; it's sloppy.
Related
I need to pump COM messages while waiting for an event to fix a deadlock. It's better to pump as few messages as possible just to process that COM call. The best candidate for this role is CoWaitForMultipleHandles but starting from Vista it pumps WM_PAINT in addition to COM messages. Pumping WM_PAINT is too dangerous for me from re-entrance perspective and I don't want to install a custom shim database as a solution for this problem.
I'm trying to pump COM messages sent to the hidden message-only window manually.
I have found two ways to get HWND of the hidden window:
((SOleTlsData *) NtCurrentTeb()->ReservedForOle)->hwndSTA using ntinfo.h from .NET Core. This seems to be undocumented and not reliable solution in terms of future changes.
Find window of OleMainThreadWndClass as suggested in this question. The problem is that CoInitialize does not create the window. It is created later on first cross-apartment call which may or may not happen in my application. Running the search loop every time I need HWND is bad from performance perspective but caching HWND seems impossible because I don't know when it's created.
Is there a way to determine if the hidden window is created for the current apartment? I suppose it will be cheaper than the loop and then I could find and cache HWND.
Is there a better way to pump COM messages without pumping WM_PAINT?
Update: you can force the window creation by calling CoMarshalInterThreadInterfaceInStream for any interface. Then call CoReleaseMarshalData to release the stream pointer. This is what I end up doing along with the search for OleMainThreadWndClass.
WM_PAINT is generated when there is no other message in the message queue and you execute GetMessage or use PeekMessage.
But WM_PAINT is only sent if you Dispatch it. Also there is no new WM_PAINT message until a window is invalidated again.
So it depends on you if you dispatch a WM_PAINT message or not. But be aware, there are other chances of reentrances like a WM_TIMER message.
The details about this are in the docs for WM_PAINT.
From my point of view the best solution would be to set you application in a "wait" mode, that even can handle WM_PAINT in this undefined waiting state. You know when you are reentered. It is always after a WM_PAINT... or similar messages that arrive like other input messages. So I don't see any problems here. An STA has one thread and you always process messages to an end, until you execute GetMessage, launch a modal dialog or show a MessageBox. When you are inside some message handling, nothing will disturb you.
Maybe an other solution would be to wait inside a second thread for this event. This thread may not have any windows and you can translate the event to anything you need in your application.
So you question may not have enough information how this deadlock really appears. So this answer may not be sufficient.
After writing als this I tend to the opinion that this is an XY problem.
I have a dialog-based MFC application which needs to stop Windows Wifi service in order to run correctly, but I want to enable it again when my application exits.
So I thought I'd put the code that restarts the service in the destructor of the main dialog class.
Now it has come to my attention that others put their code which should be run during program termination into a WM_CLOSE message handler.
Both ways seem to work, but I would like to know if there are downsides to either way.
For MFC dialog based application you can place finalization code to application class InitInstance method, immediately after main dialog DoModal call. For other MFC application types (MDI, SDI) finalization code is usually placed to ExitInstance method.
The difference between dialog based application and SDI/MDI applications, is that InitInstance in dialog based applications returns FALSE, and application exits - all action is done in the main dialog DoModal call.
You can prefer to use ExitInstance for all application types, it should work as well.
Edit. If you want to make cleanup code inside of the dialog class, WM_DESTROY (already mentioned by Roger Rowland) is better place than WM_CLOSE. Sometimes we can handle WM_CLOSE message and prevent a dialog to be closed, for example, by asking "Exit the program? Yes - No". In the case you want to use some child windows, they exist in WM_CLOSE and WM_DESTROY message handlers, and don't exist in a dialog destructor. Also, message queue doesn't exist when main dialog destructor is called, so you should not use Windows messaging in this case.
Aim to maintain symmetry: if you are stopping the wifi service in a constructor, then restart it in the same class's destructor. If instead you stop the service in InitInstance, you would restart it in ExitInstance; if as a response to WM_CREATE or some other message, then restart it in WM_CLOSE, etc.
Constructors and destructors have no way of returning an error status, so normally they are better suited for simple tasks such as initialization and memory allocation/deallocation.
InitInstance and ExitInstance, as well as windows messages such as WM_CLOSE, happen at a good spot in the application's lifetime to display error messages if necessary, or to abort in response to error conditions.
I have an external application that calls my application and is supposed to end it when the job is done. The log from this external application claims it uses WM_CLOSE on my app.
How can I intercept the WM_CLOSE message in my application to do some cleanup operations? I tried at_exit() and wrapping it in a class, but I think I have the wrong approach.
The official solution for console applications is HandlerRoutine, a callback set by SetConsoleCtrlHandler. Windows will call your handler with a CTRL_CLOSE_EVENT argument in case of a WM_CLOSE exit.
When you're using a class method with SetConsoleCtrlHandler, it must be a static method - Windows won't provide you with a this pointer.
You could just handle WM_CLOSE in your message loop to do whatever cleanup is necessary, or even abort the close (by returning 1 instead of 0). See e.g. this: http://cboard.cprogramming.com/windows-programming/141438-handling-wm_close-wm_destroy.html#post1056273
Edit: for console applications, this may be of interest: http://support.microsoft.com/kb/178893
You must create hidden window using winapi, and handle WM_CLOSE message in its message loop. Is your app using any gui elements?
The easiest way I think is to call PeekMessage from time to time.
BOOL IsCloseEventReceived()
{
MSG msg;
return PeekMessage(&msg, NULL, WM_CLOSE, WM_CLOSE, PM_NOREMOVE);
}
This function should work to check if a WM_CLOSE message has been posted. It's not blocking, and you'll need to call it on a regular basis.
I might be wrong, but I think you don't need a hidden window to handle messages, a message queue is attached to your process the first time you call a messages-related function, like PeekMessage. However if you receive a WM_CLOSE message prior to your first call of this function it might be lost.
I have a third party encryption library, which may create a MessageBox if key creation fails. The failure can be caused by bad random number generation or other rarities, and in most cases, trying again will result in success. My code will attempt key creation up to three times before deciding it failed.
Now, the issue is that the program may be used with automation. If a MessageBox is created during automation, it will block the process forever, because there's nobody to click the 'OK' button.
Does anyone know of a way to catch when this message box is created and automatically close it?
Anything is fair game, as long as it's not something that will make security suites angry. This means no hooking or code tunneling.
In summary, I need to catch when a MessageBox is created and close it. The MessageBox's creation is outside of my control. Modifying the code at runtime is not acceptable.
Also, I've noticed there are some other similar questions, but they don't have the same requirements.
EDIT: Additional note, I can find the message box via searching through all windows until I find one with a matching title and then send it a WM_CLOSE message, but I don't think this is a great solution. I also have no guarantee that the message box has been/will be displayed, or how long after my call it will be displayed. It could display instantly, it could display 1200 ms later, or it could not display at all.
Just before you begin the encryption process, install a WH_CBT hook, and in its callback watch for an nCode of HCBT_CREATEWND. If you get a matching class name ('#32770 (Dialog)' ?) and a matching title either return a nonzero value from the callback, or if that doesn't work post a WM_CLOSE (or a BM_CLICK to a relevant button if selecting an option is necessary). Uninstall the hook after the process for not messing with every possible dialog your application pops up.
That sounds like bad design on the part of that library. Generally any sort of utility library (like encryption) has no business invoking any kind of GUI (unless you explicitly ask it to).
Is there possibly some configuration or setting in this library that could disable its use of message boxes?
If not, I'd suggest that you might want to investigate using a different library. After all, if the designers of this library have already made this kind of poor design decision once, then there may be other unfortunate surprises lurking in there.
You can hope that it will be found by GetForegroundWindow, but this may catch other applications. The more brute force way is to iterate over all windows with EnumWindows looking for something that has a caption or text equal to this shown by the library.
I have once "remote controlled" an application by sending mouse click events to some controls. I guess you would have to do this in a separate thread that is watching for Events if a window is opened. Pretty ugly but working...
Create a new thread. If your function fails and a Message Box is opened, obtain a handle to the message box by looping through the windows (GetTopWindow, GetNextWindow) and comparing the window's process id to the one returned from GetCurrentProcessId().
Or, you can avoid all the hard work and just hook the MessageBox API with detours. It's not very hard, and if you don't want to pay for detours, you can do it manually.
Call VirtualProtect and set the memory protection at MessageBox at PAGE_EXECUTE_READWRITE
Create a naked function, and use it as a trampoline.
Create a function identical in parameters to MessageBox (this will be your hook)
Create a jump from MessageBox to your hook function.
I'm developing an interface for an add-on to a game. I can't use the game API (for several reasons including the fact that the code must be game-agnostic) and I need to get keyboard input from the user so I've decided to use a keyboard hook (WH_KEYBOARD) to process user input when certain conditions are met.
The problem is that while I can receive and process the input correctly, when my hook returns TRUE instead of CallNextHookEx the system seems to take up a lot of time (well over 800ms) before letting things go on as expected and that's not acceptable because it doesn't even allow for a fluid typing experience.
What I have to achieve is preventing the key press message to reach the WndProc, so the question is: what can I do to achieve my target without hurting the game performance so much that the result will be unacceptable?
EDIT: due to specific requirements (games using anticheats which might create problems with my code despite it's not cheating-related) subclassing the active wndproc is not an option.
First you need your DLL to be injected into the target process, either by hooks, or by any other way.
Find the window handle of interest.
Obtain the current window procedure of that window, by calling GetWindowLongPtr(wnd, GWLP_WNDPROC), and save it.
Sub-class the window, by calling SetWindowLongPtr( wnd, GWLP_WNDPROC, &NewWndProc ) where NewWndProc is your DLL-implemented message procedure.
Inside NewWndProc you'll want to process keyboard messages (there're a dozen of them, type "keyboard input" in MSDN index, I can't post more then 1 link). For the rest of windows messages call the original window procedure you've saved during (3), and return the value it returned. Don't call it directly, use CallWindowProc instead.
This way is not very reliable, some antivirus and anti-bot (e.g. "warden client") software might not like it, and debugging may be challenging.
However it should work.
A keyboard hook should not make things that slow. There's probably something else going on that causes the 800ms delay. Is it still slow if your hook does nothing and simply returns TRUE?
If you want to prevent from message to arrive to the WndProc then you need to subclass using SetWindowLong, this way you will be able to catch all messages and decide if to continue their route.
As much as I don't like answering my own question I've found the cause of the delay. The message pump of the games I've tested my code against was implemented with a while(PeekMessage) { GetMessage... } and removing the keyboard input message somehow caused GetMessage to block for sometime. Using PostMessage and WM_NULL helped preventing GetMessage from blocking.