Turning Off the Exception Message Box

[Previous] [Next]

There might be times when you don't want the exception message box to be displayed if an exception occurs. For example, you might not want the message box to appear in the shipping version of your product. If it did appear, it could easily lead an end user to accidentally start debugging your application. An end user needs only to click on the Cancel button in the message box to enter unfamiliar, scary territory—the debugger. You can use a variety of methods to prevent this message box from appearing.

Forcing the Process to Die

To prevent UnhandledExceptionFilter from displaying the exception message box, you can call the SetErrorMode function shown here, passing it the SEM_ NOGPFAULTERRORBOX identifier:

 UINT SetErrorMode(UINT fuErrorMode); 

Then, when UnhandledExceptionFilter is called to handle the exception, it sees that you have turned on this flag and immediately returns EXCEPTION_EXECUTE_HANDLER. This causes the global unwind and then executes the handler in BaseProcessStart or BaseThreadStart. The handler terminates the process.

I personally don't like this method because the user is given absolutely no warning; the application just vanishes.

Wrapping a Thread Function

Another method you can use to disable the message box is to place a try-except block around the entire contents of your primary thread's entry-point function (main, wmain, WinMain, or wWinMain). Make sure that the exception filter always evaluates to EXCEPTION_EXECUTE_HANDLER so that the exception is handled, preventing the system from calling the UnhandledExceptionFilter function.

In your exception handler, you can display a dialog box with some diagnostic information. The user can copy the information and report it to your customer service lines to help you track the sources of problems in your application. You should create the dialog box so that the user can only terminate the application and not invoke the debugger.

The problem with this method is that it catches only exceptions that occur in your process's primary thread. If any other threads are running, and an unhandled exception occurs in one of these threads, the system calls the built-in UnhandledExceptionFilter function. To fix this, you would need to include tryexcept blocks in all your secondary thread entry-point functions as well.

Wrapping All Thread Functions

Windows offers another function, SetUnhandledExceptionFilter, which allows you to wrap all your thread functions in an SEH frame:

 PTOP_LEVEL_EXCEPTION_FILTER SetUnhandledExceptionFilter( PTOP_LEVEL_EXCEPTION_FILTER pTopLevelExceptionFilter); 

After your process calls this function, an unhandled exception occurring in any of your process's threads causes your own exception filter to be called. You need to pass the address of your filter as the parameter to SetUnhandledExceptionFilter. The prototype of your filter function must look like this:

 LONG UnhandledExceptionFilter(PEXCEPTION_POINTERS pExceptionInfo); 

You'll notice that this function is identical in form to the UnhandledExceptionFilter function. You can perform any processing you desire in your exception filter as long as you return one of the three EXCEPTION_* identifiers. The following table shows what happens when each identifier is returned.

Identifier What Happens
EXCEPTION_EXECUTE_HANDLER The process simply terminates because the system doesn't perform any action in its exception handler block.
EXCEPTION_CONTINUE_EXECUTION Execution continues at the instruction that raised the exception. You can modify the exception information referenced by the PEXCEPTION_POINTERS parameter.
EXCEPTION_CONTINUE_SEARCH The normal Windows UnhandledExceptionFilter function executes.

To make the UnhandledExceptionFilter function the default filter again, you can simply call SetUnhandledExceptionFilter and pass it NULL. Also, whenever you set a new unhandled exception filter, SetUnhandledExceptionFilter returns the address of the previously installed exception filter. This address will be NULL if UnhandledExceptionFilter was the currently installed filter. If your own filter is about to return EXCEPTION_CONTINUE_SEARCH, you should call the previously installed filter whose address was returned by the SetUnhandledExceptionFilter function.

Automatically Invoking the Debugger

Here is the last method for turning off UnhandledExceptionFilter's message box. In the same registry subkey mentioned earlier, there is another data value named Auto. This value indicates whether UnhandledExceptionFilter should display the message box or simply start the debugger. If Auto is set to 1, UnhandledExceptionFilter does not display a message box showing the user the exception and immediately invokes the debugger. If the Auto subkey is set to 0, UnhandledExceptionFilter displays the exception message box first and operates as described earlier.



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net