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.
Related
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.
Scenario:
A TPageControl with two TTabSheets
A TWebBrowser on the non-visible tab sheet
WebBrowser->Navigate called during form creation
If the user simply runs the form and exits, then during application shutdown, an access violation is generated:
First chance exception at $507C1413. Exception class $C0000005 with message 'access violation at 0x507c1413: read of address 0x00000010'. Process Project1.exe (3464)
The call stack in the debugger contains only a single entry, which suggests that the call stack is being corrupted:
:507c1413 ; C:\Program Files (x86)\Embarcadero\Studio\16.0\bin\vcl220.bpl
(Another application shows the call stack as having a single entry of IsFormSizeStored.)
Switching to the browser's tab sheet, either in code or in the UI, avoids the problem. Not calling Navigate avoids the problem.
Observed in XE4 and XE8.
What's the best way of fixing this?
Following #TOndrej's suggestion, I added a FormClose event handler to delete the TWebBrowser control before the application shuts down.
This issue has been logged on the RAD Studio Quality Portal.
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.
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.
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.