Prevent Delphi COM component from showing MessageBox() - delphi

We have a Delphi 2007 COM component being executed from an ISAPI app. The COM component is hanging the app because it is attempting to display a MessageBox(). The call to MessageBox() must be occurring in the Delphi RTL becase it is not in our user code.
The app hangs, of course, because there is no one logged in at the server to clear the MessageBox().
How do we configure our Delphi project so that the Delphi RTL does not attempt to display MessageBox() on exception?

Write your own exception handler and attach it to the Application.OnException event. If an OnException event handler is present, Application won't use its default MessageBox routine. The signature is defined as:
TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;
If this is a server, you'll probably want to write the exception information to a log, and possibly return some error to the user.

What does the messagebox say? I'm assuming it's an exception. Why don't you put an exception handler around the code in the COM component, and log the exception in a different way? (E.g., using the Event Log). And/or fix the problem that's leading to the exception in the first place.

I don't know of any direct way in Delphi but what you can do is write a small script in AutoIT/AutoHotKey and keep that script running in system tray, so that it will automatically close the MessageBox.
Believe me it is very simple.
http://www.autoitscript.com/autoit3/index.shtml
http://www.autohotkey.com/
HTH

Is it possible to compile the application as a Console app? I'm not sure if you can do this and still have it contain COM object, this would prevent message dialogs from being shown I'm sure.
Just a thought.

I've created a unit to hook MessageBox/MessageDlg calls (via detouring), so I can suppress these calls in a Windows Service (to avoid "hanging" of my service dll because of some stupid code of someone else with a messagebox call in it).
If you want it, I can search this unit and send it to you.

Related

How to avoid "the procedure entry point could not be located in the dynamic link library" message raised for SysUtils.LoadPackage function

I'm using SysUtils.LoadPackage function in order to load dynamic packages.
Sometimes, it can happen that some packages are not synchronized and an error like this appears (Picture taken from internet):
In those cases, I would like to manage the exception avoiding the error dialog.
Unfortunately, I noticed that the message is shown in the LoadPackage procedure.
Is there a workaround or another function that doesn't raise error dialogs?
You can suppress this dialog which is raised by the system rather than Delphi.
First of all you need to set the process error mode to suppress the Windows dialog that you have shown in your question. Do that at program startup by calling this function:
procedure SetProcessErrorMode;
var
Mode: DWORD;
begin
Mode := SetErrorMode(SEM_FAILCRITICALERRORS);
SetErrorMode(Mode or SEM_FAILCRITICALERRORS);
end;
The error mode defaults to showing dialogs for critical errors for reasons of backwards compatibility with ancient versions of Windows. Microsoft say:
Best practice is that all applications call the process-wide SetErrorMode function with a parameter of SEM_FAILCRITICALERRORS at startup. This is to prevent error mode dialogs from hanging the application.
The code above does exactly that. And suppresses the dialog shown in the question.
Then when you call LoadPackage you need to catch EPackageError exceptions that are raised and deal with them however you choose. These EPackageError exceptions are the Delphi runtime's way of telling you that the call to LoadPackage failed.
Reading between the lines, I'd guess that you already handle these exceptions and the error mode setting is all that you need to do.

How to disable all exception raising in Delphi?

Is there a way to disable all the dialog boxes when an exception or error occurs(like access violations, indy socket errors, timeouts etc.)? They are thrown sometimes in my program, but these errors aren't fatal in any way and can be ignored, just the dialog boxes are disturbing. I use Delphi 7.
If you just don't wont to show the exception window then go to:
Tools/Options/Debugger Options/Language Exceptions and disable CheckBox Notify on language exceptions. That is walid for Delphi 2010.
(I don't remember if it is the same CheckBox in Delphi 7).
EDIT:
In some cases the exceptions are unavoidable, specially when we are working with unknown files from internet. So, I believe that your exceptions are handled properly under Indy, just switch-off Notify on language exceptions
You can customize Application.OnException event. But IMVHO...
Application.OnException suits best to log exceptions which you forgot to handle.
Application.OnException should be used to catch exceptions only when you desperately need performance (in this case you should anticipate broken execution paths).
And:
Access violations are fatal errors - you have to trace and get rid of all AV's.
You can't hide exception dialogs just by Application.OnException override - you should use try finally/except in right way.
Bypass the Application.OnException event. However I would NOT recommend hiding every exception, IMHO that is poor design.
# GJ - Delphi 2007 has that check box. But again as was mentioned above, access violation ain't the kind of exceptions that one should ignore.

How to supress EAccessViolation Finalization exception (mshtml.dll)

We use TWebBrowser in our application.
on some of my customers computers (IE9/Win7) after my app terminates, it throws an Exception: "Access violation at address XXXX in module 'mshtml.dll'. Read of address XXXX" with endless loop of exception messages... very ugly :/
this only happens on very few computers (so far with only IE9/Win7).
I cannot reproduce this exception on my PC.
I also use JclDebug which is the last unit defined in my main dpr uses clause - it is not catching this exception.
How to completely supress this Exception?
The application is written in D5.
Wild guess... there is a callback (event) from IE when your Application is in the destructor and your TWebBrowser is (at least partially) destroyed.
You can try to explicitly Free the TWebBrowser earlier, see if you have any event handler that could mess around, make sure you use Release on the form that holds it...
Hard to tell without having the code.

Coinitialize error on IntraWeb using ADO

Already asked on the Evil Exchange, but as always that was no help. I'm having this problem today:
When creating a stand alone web application using IntraWeb, I get this exception in the IDE when I try to test out a session from my app in the browser:
First chance exception at $7C812A6B.
Exception class EOleSysError with
message 'CoInitialize has not been
called'. Process WebContactManager.exe
(1112)
If I click "continue" on the IDE exception dialog, the browser itself just shows:
200 OK
...rather than the controls on my main form.
This error does not seem to occur when I replace ADO with other database components such as dbExpress or BDE.
What is this error telling me, and how do I fix it?
(Note I'm using the stock "VCL for the Web" IntraWeb components which come built-in with D2007).
Thanks in advance for any and all help!
The "solution" provided in the link you quoted is basically wrong or at least incomplete. Only by setting ServerController.ComInitialization to ciMultiThreaded to true IW will gurantee that every thread will get COM initialized correctly. (for example think about Ajax callbacks)
If you create your own custom threads then you will have to call CoInitialize for that thread on your own though - as Intraweb does not know about your custom threads.
Just found an answer to this here:
I found a more elegant solution as the
whole problem originated from using
Intraweb, I rather get Intraweb to
initialise com for me. This sorts it
out nicely.
When using your MS SQL DbExpress
driver or ADO driver with Intraweb,
you must set the ComInitialization
property in the ServerController to
‘ciMultiThreaded’.
This will eliminates the "CoInitialize
has not been called" error.

Is there a way to disable the hint for a TOpenDialog in delphi?

I have a TOpenDialog component I am creating on runtime and I want to disable the hint that pops up over files when it is used. I have not written any exrta code for this than creating the object, executing the object and extracting the filename,, then freeing the instance.
Can I do what I want to do? If so, how do I do this?
I googled for "opendialog crash tooltip" and the first hit gave me this. The solution for their problem (and probably yours) is this:
[...]
You only need to add this modification to the first form of your application:
uses ActiveX;
initialization
OleInitialize(nil);
finalization
OleUninitialize
end.
Since this is a Windows common dialog, you may have to jump in and hook into the dialogproc and manually try and process the tooltip messages. You can look here for a start about how to customize the common dialogs; http://msdn.microsoft.com/en-us/library/ms646951.aspx. You can also look at creating your own TOpenDialog descendant and override the WndProc protected method to get access to the dialog messages and notifications. I suspect you'd also need to do some deeper hooking and start getting into dealing with the explorer shell. The file list in that dialog is actually an instance of parts of the Windows Explorer shell.
Another question is what is it you're trying to accomplish by hiding this information from the user? Maybe there is some other solution to what you're trying to do rather than disabling some intrinsic functionality?

Resources