The original exceptions are unchanged code and most likely your COM components. A stack trace indicates that exceptions fall into your message loop, and this may be the result of cross-calling apartments from your .NET code into a COM object in STA (Single Threaded Apartment). Then, method calls are then marshaled and sent using window messages to the component.
There is nothing wrong with making cross calls to the apartment, but I saw that some COM components did not perform proper marshaling when they were pointed to by pointers from another apartment and did not know about the flow rules in COM at all. If your application has any kind of multithreading, you definitely need to learn this. These βbrokenβ COM objects will behave well when called from the main STA thread, but may fail when called or created on different threads.
More specifically: Assume that the application user interface thread at startup enters the STA (Single Threaded Apartment) and creates a COM component. Then you create a new thread (which will be in another apartment), and from this thread you call the method on the COM component. This is a cross call apartment. The COM component can only be run in a user interface thread (a thread in the apartment in which it lives). In the COM infrastructure, note that you are cross-calling the apartment, and it will serialize the call to the buffer (call marshal in COM lingua). This buffer is then sent to the user interface stream using a Windows message. If your application does not have a window, COM will create a hidden window to receive these messages. Then the message loop of your application will unpack the marshall call and execute it in the user interface thread.
Now let's assume that either you or the COM component do not understand the rules of COM apartments and sorting. One of the arguments in a method call is a pointer or something that resolves to a pointer, and that pointer is not valid in the apartment of the COM component. Then, when the COM component cancels the pointer, you get an error. The .NET runtime will detect this and throw one of two types of exceptions that you see. However, this exception is thrown into the message loop of the user interface stream, in some code that you do not have access to. Using the try-catch block on the caller does not help catch the exception, because it is thrown in a different thread. In any case, you should not catch an exception, because this is a sign of something really bad in your application.
For writing, error code -2147467259 is 0x8004005, which corresponds to E_FAIL. Not very useful, but the errors you experience are most likely due to invalid pointers used in the COM component.
To fix this, you will need to use COM components correctly and / or fix any broken code in the components.
Martin liversage
source share